2

I have a list of files and that list may contains duplicate file name but those files resides in different location with different data. Now when I am trying to add those files in zip I am getting java.lang.Exception: duplicate entry: File1.xlsx. Please suggest how I can add duplicate file names. One solution is like if I can rename the dulpicate file as File , File_1,File_2.. But I am not sure how I can achieve it. Please help !!! Below is my working code if all the file names are unique.

Resource resource = null;
    try (ZipOutputStream zippedOut = new ZipOutputStream(response.getOutputStream())) {

        for (String file : fileNames) {

             resource = new FileSystemResource(file);

             if(!resource.exists() && resource != null) {

            ZipEntry e = new ZipEntry(resource.getFilename());
            //Configure the zip entry, the properties of the file
        e.setSize(resource.contentLength());
            e.setTime(System.currentTimeMillis());
            // etc.
        zippedOut.putNextEntry(e);
            //And the content of the resource:
            StreamUtils.copy(resource.getInputStream(), zippedOut);
            zippedOut.closeEntry();

             }
        }
        //zippedOut.close();
        zippedOut.finish();

    return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=download.zip").body(zippedOut);
    } catch (Exception e) {
        throw new Exception(e.getMessage()); 
    }
abhishek chauhan
  • 367
  • 2
  • 6
  • 15
  • *FYI:* The null check in `if(resource.exists() && resource != null)` is meaningless. If `resource` had been null, the attempt to call `exists()` would have thrown `NullPointerException` *before* you got to the null check. Any good IDE should have warned you about this, e.g. Eclipse will say: *"Redundant null check: The variable `resource` cannot be null at this location"* – Andreas Jul 19 '18 at 17:58
  • @Andreas Yeah that’s my bad I have to use ! Operator for exist. I can change it. But here the actual question is how to add duplicate file name in ZipEntry if you can help on that it would be good. – abhishek chauhan Jul 19 '18 at 18:15
  • Is this what you need? https://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure – Pavel Molchanov Jul 19 '18 at 18:35
  • @PavelMolchanov thanks for sharing but this not I am actually looking for the link you shared mainly works for directory here I my issue us how I can insert the file with same name – abhishek chauhan Jul 19 '18 at 18:41

2 Answers2

6

One solution is like if I can rename the duplicate file as File, File_1, File_2, ... But I am not sure how I can achieve it.

Build a Set of names, and append a number to make name unique, if needed, e.g.

Set<String> names = new HashSet<>();
for (String file : fileNames) {

    // ...

    String name = resource.getFilename();
    String originalName = name;
    for (int i = 1; ! names.add(name); i++)
        name = originalName + "_" + i;
    ZipEntry e = new ZipEntry(name);

    // ...

}

The code relies on add() returning false if the name is already in the Set, i.e. if name is a duplicate.

This will work even if given names are already numbered, e.g. here is example of mapped names given the order of incoming names:

foo_2
foo
foo   -> foo_1
foo   -> foo_3        foo_2 was skipped
foo   -> foo_4
foo_1 -> foo_1_1      number appended to make unique
Andreas
  • 154,647
  • 11
  • 152
  • 247
0

this solution copies the index style used by windows, "filename (n).doc", respecting the file extensions

Map<String, Integer> nombresRepeticiones = new HashMap<String, Integer>();
for(FileDTO file : files) {
    String filename = file.getNombre();
    if (nombresRepeticiones.containsKey(filename)) {
                    
        int numeroRepeticiones = nombresRepeticiones.get(filename) + 1;                     
        String base = FilenameUtils.removeExtension(filename);
        String extension = FilenameUtils.getExtension(filename);
                    
        filename = base + " (" + numeroRepeticiones + ")"; 
                    
        if (extension != null && !extension.isEmpty()) {
            filename = filename + "." + extension;
        }
                    
        nombresRepeticiones.put(file.getNombre(), numeroRepeticiones);                      
    }
    else {
        nombresRepeticiones.put(filename, 0);
    }
                
    ZipEntry ze = new ZipEntry(filename);
    zos.putNextEntry(ze);                                
    zos.write(IOUtils.toByteArray(file.getContenido().getInputStream()));
    zos.closeEntry();
}