当前位置: 首页 > 知识库问答 >
问题:

ZipOutputStream不会为目录创建新条目

况安然
2023-03-14

我试图在. 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;
    }

要压缩的方法:

 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){
        }

    }

共有2个答案

吕越彬
2023-03-14

我有点惊讶这竟然有用。

当您的zip()方法递归调用自身时,它会创建一个新的FileOutputStream,其文件名与前一次调用相同。这意味着您的递归调用将在彼此之上写入,而不是附加到单个zip文件。

您应该只打开FileOutputStream/ZipOutputStream一次,然后使用它压缩所有文件和目录。

这意味着重写一些代码,以便在压缩的第一级创建zipoutpstream,然后调用内部方法zip(path,zipoutpstream)。递归调用还必须调用这个zip(path,zipoutpstream)方法。

这看起来像

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
}
曾飞沉
2023-03-14
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; 

public class ZipFolders
{
    public static void main(String[] args) throws IOException
    {    
        List<String> listOfDir = new ArrayList<String>();

        String dirpath1 = "/home/administrator/Documents/ZipTest/folder1";
        String dirpath2 = "/home/administrator/Documents/ZipTest/folder2";

        String ZipName = "/home/administrator/Documents/ZipTest/output.zip";
        listOfDir.add(dirpath1);
        listOfDir.add(dirpath2);

        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(ZipName));
        zipDirectories(listOfDir,zos); 
        zos.close(); 
        System.out.println("Zip Created Successfully");
    }

    private static void zipDirectories(List<String> listOfDir, ZipOutputStream zos) {
        for(String dirPath:listOfDir){
            try {
                zipdirectory(dirPath, zos);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static void zipdirectory(String dirpath, ZipOutputStream zos) throws IOException
    {
        File f = new File(dirpath);
        String[] flist = f.list();
        for(int i=0; i<flist.length; i++)
        {
            File ff = new File(f,flist[i]);
            if(ff.isDirectory())
            {
                zipdirectory(ff.getPath(),zos);    
                continue;
            }
            String fileName = ff.getPath().substring(ff.getPath().lastIndexOf('/'));

            String folder = dirpath.substring(dirpath.lastIndexOf('/')+1);

            ZipEntry entries = new ZipEntry(folder+fileName);
            zos.putNextEntry(entries);
            FileInputStream fis = new FileInputStream(ff);
            int buffersize = 1024;
            byte[] buffer = new byte[buffersize];
            int count;
            while((count = fis.read(buffer)) != -1)
            {
                zos.write(buffer,0,count);    
            }
            fis.close();
        }
    }
}
 类似资料:
  • 现在你已经知道了怎样用CodeIgniter从数据库中读取数据,但还不知道怎样往数据库中写入数据。在这一节中,你将学到通过怎么扩展之前写过的新闻控制器和数据模型来实现这一功能。 创建一个表单 为了向数据库里输入数据,你需要创建一个表单来输入需要被存储的信息。这就是说你需要一个带两个输入域的表单,一个用来输入标题,一个用来输入内容。另外,你可以通过数据模型中的标题来取得slug。在 applicat

  • 现在你已经知道如何通过 CodeIgniter 从数据库中读取数据了,但是你还没有 向数据库中写入数据。在这一节,你将继续完善前文中创建的 News 控制器和模型, 添加上这一功能。 创建一个表单 为了向数据库中写入数据,你需要先创建一个表单用来填写要存储的信息,这意味着 你的表单里需要包含两项:一项代表标题,另一项代表内容。你可以在模型中通过代码 从标题中提取出 slug。在文件 applica

  • 问题内容: 我正在尝试为mongodb uni课程做作业。他们给了我们一些文件,说明是: 然后跑 由于某些原因,npm install不会创建node_modules目录,但是我看不到任何构建错误: 问题答案: 这就是您所需要的。它将为您动态创建package.json文件。

  • 问题内容: 我正在使用Eclipse和jdk1.7。我正在使用文件处理程序制作一个基本程序,其中将在目录内创建一个输出目录。但是,当我运行该程序时,输出显示为false并且未创建目录。我以为输出错误,因为存在同名目录,但这不是原因。所以我需要帮助。这是我的代码: 其输出为false,但尚未创建目录。我该如何解决这个问题?这不仅在此程序中-我在其中调用该方法的每个程序都存在相同的问题。 问题答案:

  • 本文向大家介绍Kafka 新建的分区会在哪个目录下创建?相关面试题,主要包含被问及Kafka 新建的分区会在哪个目录下创建?时的应答技巧和注意事项,需要的朋友参考一下 在启动 Kafka 集群之前,我们需要配置好 log.dirs 参数,其值是 Kafka 数据的存放目录, 这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘 上用于提高读写性能。 当然我们也可以配置 l

  • 本文向大家介绍Kafka新建的分区会在哪个目录下创建相关面试题,主要包含被问及Kafka新建的分区会在哪个目录下创建时的应答技巧和注意事项,需要的朋友参考一下 我们知道,在启动 Kafka 集群之前,我们需要配置好 参数,其值是 Kafka 数据的存放目录,这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。当然我们也可以配置 参数,含义一样。只需要设