创建具有相同名称的多个文件的zip

时间:2020-04-22 07:03:20

标签: java java-8 zip zipfile

我想将多个文件从不同的位置压缩到一个。

我推荐了https://examples.javacodegeeks.com/core-java/util/zip/create-zip-file-from-multiple-files-with-zipoutputstream/

这是我的代码

公共类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);
    }
}

}

这将引发异常: 创建zip文件时出错:java.util.zip.ZipException:重复项:dsdc.zip

有什么方法可以检查文件是否存在zip流中?因此,在那种情况下,我可以将_1附加到重复的文件名上?

2 个答案:

答案 0 :(得分:2)

在OpenJDK 8中,这由ZipOutputStream中的私有字段“名称”处理,该私有字段未公开公开。显然,您应该亲自处理。

只有一个HashSet,其中包含您成功添加到zip文件中的文件名,并在尝试添加新文件之前检查该名称是否先前可见。如果是这样,请进行相应的修改。

也就是说,如果可能将同一文件的多个副本添加到zip文件中,则应该重新考虑解决方案设计。要么包含目录以使文件唯一,要么跳过以前看到的所有内容。

答案 1 :(得分:0)

一种解决方案是:

            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ørnRavn也提出了类似的建议。 但是还有其他方法吗?