如何使用 Java 压缩/解压缩文件夹及其所有文件和子目录?

Posted

技术标签:

【中文标题】如何使用 Java 压缩/解压缩文件夹及其所有文件和子目录?【英文标题】:How to zip/upzip a folder and all of its files and subdirectories using Java? 【发布时间】:2012-09-16 19:14:24 【问题描述】:

我阅读这篇文章是为了学习如何使用 Java 压缩/解压缩文件。我使用this 来指导我,它在将所有文件压缩到一个文件夹中时效果很好,但是当我用一个包含更多文件夹的文件夹对其进行测试时,它不起作用,它抛出了以下错误:

java.io.FileNotFoundException: assets (Access is denied) //assets is the name of the folder I tried to zip
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at Zip.main(Zip.java:24)

这是我正在使用的类,您将看到它与上一个链接中的 代码示例 4:Zip.java 类代码相同:

import java.io.*;
import java.util.zip.*;

public class Zip 
   static final int BUFFER = 2048;
   public void zip() 
      try 
         BufferedInputStream origin = null;
         FileOutputStream dest = new 
           FileOutputStream("H:\\myfigs.zip");
         CheckedOutputStream checksum = new 
           CheckedOutputStream(dest, new Adler32());
         ZipOutputStream out = new 
           ZipOutputStream(new 
             BufferedOutputStream(checksum));
         //out.setMethod(ZipOutputStream.DEFLATED);
         byte data[] = new byte[BUFFER];
         // get a list of files from current directory
         File f = new File(".");
         String files[] = f.list();

         for (int i=0; i<files.length; i++) 
            System.out.println("Adding: "+files[i]);
            FileInputStream fi = new 
              FileInputStream(files[i]);
            origin = new 
              BufferedInputStream(fi, BUFFER);
            ZipEntry entry = new ZipEntry(files[i]);
            out.putNextEntry(entry);
            int count;
            while((count = origin.read(data, 0, 
              BUFFER)) != -1) 
               out.write(data, 0, count);
            
            origin.close();
         
         out.close();
         System.out.println("checksum: "+checksum.getChecksum().getValue());
       catch(Exception e) 
         e.printStackTrace();
      
   
 

应该进行哪些更改,以便此代码可以将文件夹内的文件夹及其所有文件压缩到一个 zip 文件中?

【问题讨论】:

【参考方案1】:

zip 条目需要指定存档中文件的路径。您无法将文件夹添加到 zip 存档 - 您只能添加文件夹中的文件。

命名约定是使用正斜杠作为路径分隔符。如果您正在压缩包含以下文件/子目录的文件夹:

c:\foo\bar\a.txt
c:\foo\bar\sub1\b.txt
c:\foo\bar\sub2\c.txt

zip 条目名称为:

a.txt
sub1/b.txt
sub2/c.txt

因此,要修复您的算法,请在 for 循环中添加 isDirectory(),然后递归地将任何子目录中的文件添加到 zip。可能最好的方法是有一个方法:

addDirectoryToZip(String prefix, File directory, ZipOutputStream out)

这里有一个解决问题的方法:java.util.zip - Recreating directory structure

【讨论】:

ZipEntry.isDirectory 声明 ...目录条目被定义为名称以“/”结尾的条目,在向 Zip 文件添加条目时,您只需需要在条目名称后面加上斜杠,不需要添加任何内容,只需要条目 非常感谢,这对我帮助很大。 @MadProgrammer 提出了一个很好的观点 - 如果您试图让 zip 存档重新创建一个空文件夹,您确实需要插入一个文件夹名称以正斜杠结尾的 ZipEntry,并且不要添加内容。

以上是关于如何使用 Java 压缩/解压缩文件夹及其所有文件和子目录?的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地压缩此文件夹,以便可以使用 Java 以最小的工作空间解压缩

使用SSH分卷压缩,下载到本地如何解压缩?

免费毕设JAVA文件压缩与解压缩实践(源代码+论文)

如何使用shell调用Winrar压缩及解压缩文件

使用 Python 解压缩文件并返回它创建的所有目录

Linux命令(十八) 压缩或解压缩文件和目录 gzip gunzip