原文:http://hello-nick-xu.iteye.com/blog/2002613
在web开发过程中,进行文件的压缩传输是一种常见的需求。比如一种场景:用户需要下载定时生成的报表,我们需要先对报表文件进行压以方便用户的下载,并减少文件的存储空间。
事实上,JDK已经提供了文件压缩/解压缩的支持,可以生成zip/gzip的压缩格式,并且支持支持“校验和”以检查压缩文件的完整性。通常会使用CRC(循环冗余校验)算法进行校验。
遗憾的是,JDK的文件压缩功能无法处理文件名称包含中文的问题。为此,我们需要用到ant.jar第三方开源支持包。
如下所示代码,采用Junit 4进行压缩功能的测试:
package com.test.zip;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.junit.Test;
public class ZipTest {
private final String sourceDirStr = "E:/source";
private final String zipPath = "E:/dest.zip";
private static final int BUFFER_SIZE = 1024;
@Test
public void testZip() throws Exception {
ZipOutputStream zipOut = new ZipOutputStream(
new BufferedOutputStream(
new FileOutputStream(zipPath), BUFFER_SIZE));
File sourceDirectory = new File(sourceDirStr);
File[] files = sourceDirectory.listFiles();
byte[] bs = new byte[BUFFER_SIZE];
int value = -1;
for (File file : files) {
zipOut.putNextEntry(new ZipEntry(file.getName()));
BufferedInputStream bfInput = new BufferedInputStream(
new FileInputStream(file), BUFFER_SIZE);
while ((value = bfInput.read(bs, 0, bs.length)) != -1) {
zipOut.write(bs, 0, value);
}
bfInput.close();
}
zipOut.flush();
zipOut.close();
}
@Test
public void testZipWithCheckSum() throws Exception {
CheckedOutputStream checkedOutput = new
CheckedOutputStream(new BufferedOutputStream(
new FileOutputStream(zipPath), BUFFER_SIZE),new
CRC32());
ZipOutputStream zipOut = new ZipOutputStream(checkedOutput);
File sourceDirectory = new File(sourceDirStr);
File[] files = sourceDirectory.listFiles();
byte[] bs = new byte[BUFFER_SIZE];
int value = -1;
for (File file : files) {
BufferedInputStream bfInput = new BufferedInputStream(
new FileInputStream(file), BUFFER_SIZE);
zipOut.putNextEntry(new ZipEntry(file.getName()));
while ((value = bfInput.read(bs, 0, bs.length)) != -1) {
zipOut.write(bs, 0, value);
}
bfInput.close();
}
zipOut.flush();
zipOut.close();
long checkSum = checkedOutput.getChecksum().getValue();
System.out.println("checkSum : " + checkSum);
}
}
完整项目功能,参见附件