zipoutputstream不会为目录创建新条目

发布于 2025-01-22 20:02:23 字数 1973 浏览 0 评论 0原文

我正在尝试在.zip文件中创建目录,但是在.zip中只创建一个目录。我不确定为什么只创建第一个目录。 Zip()方法每次都有一个目录。

列出文件的方法:

private Set<String> listFiles(String path){

        File f = new File(path);
        Set<String> files = new HashSet<>();

        for(File file : Objects.requireNonNull(f.listFiles())){
            files.add(file.getPath());
        }
        return files;
    }

zip方法:

 private void zip(Set<String> path){
        try {
            BufferedInputStream bufferedInputStream = null;
            BufferedOutputStream bufferedOutputStream;
            ZipOutputStream zipOutputStream;

            File f;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("/sdcard/Android/data/com.kpwnapps.pmmpplugins/files/PocketMine-MP/test.zip"));
                zipOutputStream= new ZipOutputStream(bufferedOutputStream, StandardCharsets.UTF_8);

                for (String file : path){

                    f = new File(file);

                    if (f.isDirectory()){
                        zipOutputStream.putNextEntry(new ZipEntry(f.getName() + "/"));
                        zip(listFiles(f.getPath()));
                    }else {
                      
                        bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
                        zipOutputStream.putNextEntry(new ZipEntry(f.getName()));
                        IOUtils.copy(bufferedInputStream, zipOutputStream);
                        zipOutputStream.closeEntry();
                    }
                     */

                }

                if (bufferedInputStream != null){
                    bufferedInputStream.close();
                }

                zipOutputStream.flush();
                zipOutputStream.close();

            }
        }catch (Exception ignored){
        }

    }

I am trying to create directories in a .zip file but only one directory is being created in the .zip. I'm not sure why only the first directory gets created. zip() method gets called everytime theres a directory.

Method to list files:

private Set<String> listFiles(String path){

        File f = new File(path);
        Set<String> files = new HashSet<>();

        for(File file : Objects.requireNonNull(f.listFiles())){
            files.add(file.getPath());
        }
        return files;
    }

Method to zip:

 private void zip(Set<String> path){
        try {
            BufferedInputStream bufferedInputStream = null;
            BufferedOutputStream bufferedOutputStream;
            ZipOutputStream zipOutputStream;

            File f;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

                bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("/sdcard/Android/data/com.kpwnapps.pmmpplugins/files/PocketMine-MP/test.zip"));
                zipOutputStream= new ZipOutputStream(bufferedOutputStream, StandardCharsets.UTF_8);

                for (String file : path){

                    f = new File(file);

                    if (f.isDirectory()){
                        zipOutputStream.putNextEntry(new ZipEntry(f.getName() + "/"));
                        zip(listFiles(f.getPath()));
                    }else {
                      
                        bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
                        zipOutputStream.putNextEntry(new ZipEntry(f.getName()));
                        IOUtils.copy(bufferedInputStream, zipOutputStream);
                        zipOutputStream.closeEntry();
                    }
                     */

                }

                if (bufferedInputStream != null){
                    bufferedInputStream.close();
                }

                zipOutputStream.flush();
                zipOutputStream.close();

            }
        }catch (Exception ignored){
        }

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽清梦 2025-01-29 20:02:25

我很惊讶这甚至有效。

当您的zip()方法本身递归地调用时,它将创建一个新的fileOutputStream,其文件名与上一个呼叫相同。这意味着您的递归调用在彼此的顶部写入,而不是附加到单个zip文件。

您应该仅打开FileOutputStream / ZipOutputStream一次,然后将其用于将所有文件和目录缩放。

这意味着重写一些代码,以便在zipping的第一级中创建zipoutputstream,然后调用内部方法zip(path,zipoutputstream)。递归调用还必须调用此zip(路径,zipoutputstream)方法。

这看起来像

private void zip(Set<String> path) {
    // create FileOutputStream, ZipOutputStream
    ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
    // call worker method
    zip(path, zipOutputStream);
    // close output stream
    zipOutputStream.flush();
    zipOutputStream.close();
}

private void zip(Set<String> path, ZipOutputStream zipOutputStream) {
    // loop over paths
        if (f.isDirectory()) {
            zipOutputStream.putNextEntry(new ZipEntry(f.getName() + "/"));
            zip(listFiles(f.getPath()), zipOutputStream);
        }
    // end of loop over paths
}

I'm mildly surprised that this even works.

When your zip() method calls itself recursively it creates a new FileOutputStream with the same filename as the previous call. That means that your recursive calls write on top of each other instead of appending to a single zip file.

You should open the FileOutputStream / ZipOutputStream only once and then use it for zipping all files and directories.

That means rewriting some of your code so that at the first level of zipping you create the zipOutputStream and then call an internal method zip(path, zipOutputStream). The recursive calls also must call this zip(path, zipOutputStream) method.

This will look something like

private void zip(Set<String> path) {
    // create FileOutputStream, ZipOutputStream
    ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
    // call worker method
    zip(path, zipOutputStream);
    // close output stream
    zipOutputStream.flush();
    zipOutputStream.close();
}

private void zip(Set<String> path, ZipOutputStream zipOutputStream) {
    // loop over paths
        if (f.isDirectory()) {
            zipOutputStream.putNextEntry(new ZipEntry(f.getName() + "/"));
            zip(listFiles(f.getPath()), zipOutputStream);
        }
    // end of loop over paths
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文