简体   繁体   English

ZipOutputStream 不会为目录创建新条目

[英]ZipOutputStream does not create new entries for Directories

I am trying to create directories in a.zip file but only one directory is being created in the.zip.我正在尝试在 .zip 文件中创建目录,但在 .zip 中只创建了一个目录。 I'm not sure why only the first directory gets created.我不确定为什么只创建第一个目录。 zip() method gets called everytime theres a directory.每次有目录时都会调用 zip() 方法。

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:拨打 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'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.当您的zip()方法递归调用自身时,它会创建一个新的FileOutputStream ,其文件名与上一次调用相同。 That means that your recursive calls write on top of each other instead of appending to a single zip file.这意味着您的递归调用会相互叠加,而不是附加到单个 zip 文件。

You should open the FileOutputStream / ZipOutputStream only once and then use it for zipping all files and directories.您应该只打开 FileOutputStream / ZipOutputStream 一次,然后使用它来压缩所有文件和目录。

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) .这意味着重写一些代码,以便在压缩的第一级创建zipOutputStream ,然后调用内部方法zip(path, zipOutputStream) The recursive calls also must call this zip(path, zipOutputStream) method.递归调用也必须调用此zip(path, zipOutputStream)方法。

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM