import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
* @Description: Description
* @Author: 张颖辉(yh)
* @CreateDate: 2018/5/14 14:50
* @UpdateUser: 张颖辉(yh)
* @UpdateDate: 2018/5/14 14:50
* @UpdateRemark: The modified content
* @Version: 1.0
public class ZipCompressor {
static final int BUFFER = 8192;
private File zipFile;
public ZipCompressor(String pathName) {
zipFile = new File(pathName);
public void compress(String... pathName) {
ZipOutputStream out = null;
try {
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
new CRC32());
out = new ZipOutputStream(cos);
String basedir = "";
for (int i = 0; i < pathName.length; i++) {
compress(new File(pathName[i]), out, basedir);
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
public void compress(String srcPathName) {
File file = new File(srcPathName);
if (!file.exists())
throw new RuntimeException(srcPathName + "不存在!");
try {
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream,
new CRC32());
ZipOutputStream out = new ZipOutputStream(cos);
String basedir = "";
compress(file, out, basedir);
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
private void compress(File file, ZipOutputStream out, String basedir) {
/* 判断是目录还是文件 */
if (file.isDirectory()) {
System.out.println("压缩:" + basedir + file.getName());
this.compressDirectory(file, out, basedir);
} else if (file.isFile()) {
System.out.println("压缩:" + basedir + file.getName());
this.compressFile(file, out, basedir);
} else {
System.out.println("压缩:" + file.getName() + " 失败,文件或目录不存在!");
* 压缩一个目录
private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
if (!dir.exists())
return;
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
/* 递归 */
compress(files[i], out, basedir + dir.getName() + "/");
* 压缩一个文件
private void compressFile(File file, ZipOutputStream out, String basedir) {
if (!file.exists()) {
return;
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(file));
ZipEntry entry = new ZipEntry(basedir + file.getName());
out.putNextEntry(entry);
int count;
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
bis.close();
} catch (Exception e) {
throw new RuntimeException(e);
public static void main(String[] args) {
ZipCompressor zc = new ZipCompressor("G:/temp/zipf3.zip");
zc.compress("G:\\temp\\zip\\自拍1\\a", "G:\\temp\\zip\\自拍1 - 副本");
用的是上面的第一个压缩方法,两次得到的zip压缩文件的MD5为什么不同?解压后完全一样。甚至拿一个空的txt文件来压缩,结果执行两次得到的两个ZIP文件的MD5还是不一样。请问为什么?
因为你压缩文件,实际上是根据原文件,copy出一个新文件然后把这个文件压缩进zip文件中。那么,这个新文件,实际上是有“最后修改时间“的,这个属性肯定是不同的。文件属性的不同,导致你把整个 ZIP 文件拉入 MD5 算法计算其散列值的时候,肯定会算出不同的散列值。
要避免这种情况出现,应该是有一些压缩参数项可以设置的。这些设置可以用于避免压缩文件本身含有其文件自身属性。
https://stackoverflow.com/questions/19523063/zip-utility-giving-me-different-md5sum-every-time-in-linux