0

I want to zip multiple files from different locations into one.

I referred https://examples.javacodegeeks.com/core-java/util/zip/create-zip-file-from-multiple-files-with-zipoutputstream/

Here is my code

public class CreateZipFileFromMultipleFilesWithZipOutputStream {

public static void main(String[] args) {

    String zipFile = "C:/archive.zip";

    String[] srcFiles = { "C:/data1/srcfile1.txt", "C:/data2/srcfile2.txt", "C:/data3/srcfile2.txt"};

    try {

        FileOutputStream fos = new FileOutputStream(zipFile);

        ZipOutputStream zos = new ZipOutputStream(fos);

        for (int i=0; i < srcFiles.length; i++) {

            File srcFile = new File(srcFiles[i]);

            ZipEntry zipEntry = new ZipEntry(srcFile.getName());
            zos.putNextEntry(zipEntry);
            zos.write(Files.readAllBytes(srcFile.toPath()));
            zos.closeEntry();
        }

        // close the ZipOutputStream
        zos.close();

    }
    catch (IOException ioe) {
        System.out.println("Error creating zip file: " + ioe);
    }
}

}

This throws an exception: Error creating zip file: java.util.zip.ZipException: duplicate entry: dsdc.zip

Is there any way to check if the file exists in zip stream? So in that case I can append _1 to the duplicate file name?

Naik Ashwini
  • 750
  • 12
  • 32
  • You know all the names you’ve already seen. Just keep track of those in a map. – Thorbjørn Ravn Andersen Apr 22 '20 at 07:35
  • Yes. That's one approach where I can track through the list and create unique id myself, but doesn't zip have such inbuild functionality where it could create a duplicate file? – Naik Ashwini Apr 22 '20 at 07:38
  • Perhaps. Open the lid and see what enabled the detection that triggered the exception and then see if this is exposed anywhere. Or you could study the javadoc. – Thorbjørn Ravn Andersen Apr 22 '20 at 07:54
  • yes.. its the name of the zipEntry, but its not exposed. – Naik Ashwini Apr 22 '20 at 09:06
  • the zip format allows storing duplicate files, so the error is a limitation of this zip implementation. there is `unzip -B` to automatically rename such duplicate files. see also [How is it that during extraction of a zip, I get two files of the same name in the same path?](https://superuser.com/questions/224164/how-is-it-that-during-extraction-of-a-zip-i-get-two-files-of-the-same-name-in-t) and [Python zipfile module creates multiple files with same name](https://stackoverflow.com/questions/22143908/python-zipfile-module-creates-multiple-files-with-same-name) – milahu Mar 31 '23 at 10:49

2 Answers2

1

In OpenJDK 8 this is handled by the private field "names" in ZipOutputStream which is not publicly exposed. You are very clearly expected to handle this yourself.

Just have a HashSet containing filenames which you successfully added to the zip file, and check if the name is previously seen before trying to add a new file. If so, modify accordingly.

That said, you should reconsider your solution design if it may add several copies of the same file to a zip file. Either include directories to make the files unique, or just skip anything previously seen.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
1

One solution is:

            Set<String> uniqueFilenames = new HashSet<>();
            for (int i=0; i < srcFiles.length; i++) {

                File srcFile = new File(srcFiles[i]);

                String name = FilenameUtils.getBaseName(srcFile.getName());
                String originalName = name;


                for (int j = 1; !uniqueFilenames.add(name); j++) {
                    name = originalName + "_" + j;
                }

                ZipEntry zipEntry = new ZipEntry(name + "." + FilenameUtils.getExtension(srcFile.getName()));
                zos.putNextEntry(zipEntry);
                zos.write(Files.readAllBytes(srcFile.toPath()));
                zos.closeEntry();

@Thorbjørn Ravn also suggested something like this. But is there any other way?

Naik Ashwini
  • 750
  • 12
  • 32