现三种不错的方法:
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
















