现三种不错的方法:

1、jdk自带的包java.util.zip.ZipOutputStream,不足之处,文件(夹)名称带中文时,

出现乱码问题,实现代码如下:

/** 
   * 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
   * @param sourceDir 如果是目录,eg:D:\\MyEclipse\\first\\testFile,则压缩目录下所有文件;
   *      如果是文件,eg:D:\\MyEclipse\\first\\testFile\\aa.zip,则只压缩本文件
   * @param zipFile 最后压缩的文件路径和名称,eg:D:\\MyEclipse\\first\\testFile\\aa.zip
   */
  public File doZip(String sourceDir, String zipFilePath) 
  throws IOException {
   
   File file = new File(sourceDir);
   File zipFile = new File(zipFilePath);
   ZipOutputStream zos = null;
   try {
    // 创建写出流操作
    OutputStream os = new FileOutputStream(zipFile);
    BufferedOutputStream bos = new BufferedOutputStream(os);
    zos = new ZipOutputStream(bos);
    
    String basePath = null;
    
    // 获取目录
    if(file.isDirectory()) {
     basePath = file.getPath();
    }else {
     basePath = file.getParent();
    }
    
    zipFile(file, basePath, zos);
   }finally {
    if(zos != null) {
     zos.closeEntry();
     zos.close();
    }
   }
   
   return zipFile;
  }  /** 
   * @param source 源文件
   * @param basePath 
   * @param zos 
   */
  private void zipFile(File source, String basePath, ZipOutputStream zos) 
  throws IOException {
   File[] files = null;
   if (source.isDirectory()) {
    files = source.listFiles();
   } else {
    files = new File[1];
    files[0] = source;
   }
   
   InputStream is = null;
   String pathName;
   byte[] buf = new byte[1024];
   int length = 0;
   try{
    for(File file : files) {
     if(file.isDirectory()) {
      pathName = file.getPath().substring(basePath.length() + 1) + "/";
      zos.putNextEntry(new ZipEntry(pathName));
      zipFile(file, basePath, zos);
     }else {
      pathName = file.getPath().substring(basePath.length() + 1);
      is = new FileInputStream(file);
      BufferedInputStream bis = new BufferedInputStream(is);
      zos.putNextEntry(new ZipEntry(pathName));
      while ((length = bis.read(buf)) > 0) {
       zos.write(buf, 0, length);
      }
     }
    }
   }finally {
    if(is != null) {
     is.close();
    }
   }  }

2、使用org.apache.tools.zip.ZipOutputStream,代码如下,

Java代码:

1. package net.szh.zip;   
2.   
3. import java.io.BufferedInputStream;   
4. import java.io.File;   
5. import java.io.FileInputStream;   
6. import java.io.FileOutputStream;   
7. import java.util.zip.CRC32;   
8. import java.util.zip.CheckedOutputStream;   
9.   
10. import org.apache.tools.zip.ZipEntry;   
11. import org.apache.tools.zip.ZipOutputStream;   
12.   
13. public class ZipCompressor {   
14.     static final int BUFFER = 8192;   
15.   
16.     private File zipFile;   
17.   
18.     public ZipCompressor(String pathName) {   
19.         zipFile = new File(pathName);   
20.     }   
21.   
22.     public void compress(String srcPathName) {   
23.         File file = new File(srcPathName);   
24.         if (!file.exists())   
25.             throw new RuntimeException(srcPathName + "不存在!");   
26.         try {   
27.             FileOutputStream fileOutputStream = new FileOutputStream(zipFile);   
28.             CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,   
29.                     new CRC32());   
30.             ZipOutputStream out = new ZipOutputStream(cos);   
31. "";   
32.             compress(file, out, basedir);   
33.             out.close();   
34.         } catch (Exception e) {   
35.             throw new RuntimeException(e);   
36.         }   
37.     }   
38.   
39.     private void compress(File file, ZipOutputStream out, String basedir) {   
40. /* 判断是目录还是文件 */
41.         if (file.isDirectory()) {   
42. "压缩:"
43.             this.compressDirectory(file, out, basedir);   
44.         } else {   
45. "压缩:"
46.             this.compressFile(file, out, basedir);   
47.         }   
48.     }   
49.   
50. /** 压缩一个目录 */
51.     private void compressDirectory(File dir, ZipOutputStream out, String basedir) {   
52.         if (!dir.exists())   
53.             return;   
54.   
55.         File[] files = dir.listFiles();   
56.         for (int i = 0; i < files.length; i++) {   
57. /* 递归 */
58. "/");   
59.         }   
60.     }   
61.   
62. /** 压缩一个文件 */
63.     private void compressFile(File file, ZipOutputStream out, String basedir) {   
64.         if (!file.exists()) {   
65.             return;   
66.         }   
67.         try {   
68.             BufferedInputStream bis = new BufferedInputStream(   
69.                     new FileInputStream(file));   
70.             ZipEntry entry = new ZipEntry(basedir + file.getName());   
71.             out.putNextEntry(entry);   
72.             int count;   
73.             byte data[] = new byte[BUFFER];   
74.             while ((count = bis.read(data, 0, BUFFER)) != -1) {   
75. 0, count);   
76.             }   
77.             bis.close();   
78.         } catch (Exception e) {   
79.             throw new RuntimeException(e);   
80.         }   
81.     }   
82. }

 

3、可以用ant中的org.apache.tools.ant.taskdefs.Zip来实现,更加简单。 

Java代码

1. package net.szh.zip;   
2.   
3. import java.io.File;   
4.   
5. import org.apache.tools.ant.Project;   
6. import org.apache.tools.ant.taskdefs.Zip;   
7. import org.apache.tools.ant.types.FileSet;   
8.   
9. public class ZipCompressorByAnt {   
10.   
11.     private File zipFile;   
12.   
13.     public ZipCompressorByAnt(String pathName) {   
14.         zipFile = new File(pathName);   
15.     }   
16.        
17.     public void compress(String srcPathName) {   
18.         File srcdir = new File(srcPathName);   
19.         if (!srcdir.exists())   
20.             throw new RuntimeException(srcPathName + "不存在!");   
21.            
22.         Project prj = new Project();   
23.         Zip zip = new Zip();   
24.         zip.setProject(prj);   
25.         zip.setDestFile(zipFile);   
26.         FileSet fileSet = new FileSet();   
27.         fileSet.setProject(prj);   
28.         fileSet.setDir(srcdir);   
29. //fileSet.setIncludes("**/*.java"); 包括哪些文件或文件夹 eg:zip.setIncludes("*.java"); 
30. //fileSet.setExcludes(...); 排除哪些文件或文件夹 
31.         zip.addFileset(fileSet);   
32.            
33.         zip.execute();   
34.     }   
35. }

测试一下 

Java代码

1. package net.szh.zip;   
2.   
3. public class TestZip {   
4.     public static void main(String[] args) {   
5.         ZipCompressor zc = new  ZipCompressor("E:\\szhzip.zip");   
6. "E:\\test");   
7.            
8.         ZipCompressorByAnt zca = new ZipCompressorByAnt("E:\\szhzipant.zip");   
9. "E:\\test");   
10.     }   
11. }

下面例子演示如何通过CheckedOutputStream和CheckedInputStream实现带验证的压缩、解压。

采用了Adler32算法,当然大家用CRC32算法也可以。

通过FilenameFilter方法,取得workspace/你的工程目录下的所有txt文件,但不包含子目录下的txt文件。

用途:主要用于需要确保压缩文件在压缩跟解压的无误操作,确保完全相同。

压缩例子代码:


package ajava.code.javase;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.Adler32;

public class AjavaZipWithChecksum {
    public static void main(String[] args) {
        try {
            String target = "ajavachecksum.zip";

            FileOutputStream fos = new FileOutputStream(target);

            //使用Adler32算法创建CheckedOutputStream校验输出流
            CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32());
            ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(checksum));

            int size = 0;
            byte[] buffer = new byte[1024];

            //
            // Get all text files on the working folder.
            //通过FilenameFilter取得所有txt文件
            File dir = new File(".");
            String[] files = dir.list(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    if (name.endsWith(".txt")) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
            
            //压缩成ajavachecksum.zip
            for (int i = 0; i < files.length; i++) {
                System.out.println("压缩中...: " + files[i]);

                FileInputStream fis = new FileInputStream(files[i]);
                BufferedInputStream bis = new BufferedInputStream(fis, buffer.length);

                ZipEntry zipEntry = new ZipEntry(files[i]);
                zos.putNextEntry(zipEntry);

                while ((size = fis.read(buffer, 0, buffer.length)) > 0) {
                    zos.write(buffer, 0, size);
                }

                zos.closeEntry();
                fis.close();
            }

            zos.close();

            System.out.println(" 校验码  : " + checksum.getChecksum().getValue());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


解压例子代码:

package ajava.code.javase;

import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.CheckedInputStream;
import java.util.zip.Adler32;

public class AjavaUnzipWithChecksum {
    public static void main(String[] args) {
        String zipname = "ajavachecksum.zip";

        try {
            FileInputStream fis = new FileInputStream(zipname);

            //使用Adler32算法创建CheckedInputStream校验输出流
            CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));
            ZipEntry entry;

            //解压ajavachecksum.zip
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("解压中....: " + entry.getName());

                int size;
                byte[] buffer = new byte[2048];

                FileOutputStream fos = new FileOutputStream(entry.getName());
                BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length);

                while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                }
                bos.flush();
                bos.close();
            }

            zis.close();
            fis.close();

            System.out.println("校验码 = " + checksum.getChecksum().getValue());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:



压缩中...: ajava11.txt



压缩中...: ajava.txt



校验码: 783456913





解压中....: ajava11.txt



解压中....: ajava.txt



校验码 = 783456913