为什么我创建的zip文件(使用ZipOutputStream)无效?

问题描述 投票:0回答:1

我一直在尝试检索当前目录中的所有文件,创建一个 zip 文件,并将所有文件放入该 zip 文件中。目前,我可以检索所有文件,但我不确定它们是否已正确添加到 zip 文件中,因为我无法提取它;提取时遇到的具体错误是“压缩的(zipped)文件夹‘...’无效”。

下面显示的是我当前的代码。为了说明我想要做什么,我首先调用 getPath 方法,该方法只是检索当前目录的路径。然后,我调用 createZipFile 创建压缩文件,然后从当前目录创建一个文件数组。最后,我迭代这个数组,对每个文件调用 zipFile。我对该方法中的每个流使用 try-with-resources。值得注意的是,最初创建的 zip 文件并不是无效的,尽管它只包含数组中的最终文件。我将“true”添加到 FileOutputStream(用于追加),这导致了我当前的问题。

public static Path currentDirectory; // directory to zip
    public static File[] files; // files in current folder
    public static File newZip; // the created zip file

    // will retrieve all files in currentDirectory, and zip them
    public static void findFiles() {
        getPath();
        createZipFile();
        File thisFolder = new File(String.valueOf(currentDirectory)); // current folder
        files = thisFolder.listFiles(); // all files in current folder

        for (File f : files) {
            zipFile(f.getName());
        }
    }

    public static Boolean createZipFile() {
        newZip = new File("test.zip");

        try {
            if (!newZip.exists()) {
                if (newZip.createNewFile()) {
                    System.out.println("Zip file created!");
                    return true;
                }
            }   
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return false;
    }

    public static void zipFile(String fileName) {
        try (FileOutputStream fos = new FileOutputStream(newZip, true)) {
            File inputFile = new File(fileName);
            try (FileInputStream fis = new FileInputStream(inputFile)) {
                try (ZipOutputStream zos = new ZipOutputStream(fos)) {
                    ZipEntry zipEntry = new ZipEntry(fileName);
                    zos.putNextEntry(zipEntry);
                    System.out.println("Zipping file "+fileName+"!");
    
                    byte[] bytes = new byte[1024];
                    int length;
                    while ((length = fis.read(bytes)) >= 0) {
                        zos.write(bytes, 0, length);
                    }
                } catch (Exception e) {
                    System.out.println("ZOS Error: "+e.getMessage());
                }   
            } catch (Exception e) {
                System.out.println("FIS Error: "+e.getMessage());
            }
        } catch (Exception e) {
            System.out.println("FOS Error: "+e.getMessage());
        }
    }

    // sets currentDirectory, i.e. folder to zip
    public static void getPath() {
        Path currentPath = Paths.get("");
        String pathString = String.valueOf(currentPath.toAbsolutePath());
        currentDirectory = Paths.get(pathString);
    }

我尝试在 zipFile 中的 fileName 本身上使用 getBytes。我认为这会更合适地将提供的字节写入文件。但是,我再次收到无效的 zip 文件消息,并且该程序的执行时间明显更长。

我也在网上寻找解决方案,我发现一个常见的解决方案是确保流关闭。但是,由于我使用的是 try-with-resources,所以我相当确定这不适用于我。

java zip zipoutputstream
1个回答
0
投票

问题隐藏在这一行

new FileOutputStream(newZip, true)

您不能将一个拉链附加到另一个拉链上并将其视为一个大拉链。

您需要创建

ZipOutputStream
并将所有文件添加到其中。

© www.soinside.com 2019 - 2024. All rights reserved.