在java中从zip中提取后保留文件校验和

时间:2011-06-14 15:55:43

标签: java zip apache-commons checksum

这就是我想要完成的事情: 1)计算要添加到zip文件的所有文件的校验和。目前使用apache commons io如下:

final Checksum oChecksum = new Adler32();
...

//for every file iFile in folder
long lSum = (FileUtils.checksum(iFile, oChecksum)).getValue();
//store this checksum in a log

2)使用Ant zip任务压缩处理为zip的文件夹。 3)将zip中的文件逐个提取到指定的文件夹(使用公共文件io和压缩),并计算提取文件的校验和:

final Checksum oChecksum = new Adler32();    
...
    ZipFile myZip = new ZipFile("test.zip");
    ZipArchiveEntry zipEntry = myZip.getEntry("checksum.log"); //reads the filename from the log
    BufferedInputStream myInputStream = new BufferedInputStream(myZip.getInputStream(zipEntry));
    File destFile = new File("/mydir", zipEntry.getName());
    lDestFile.createNewFile();
    FileUtils.copyInputStreamToFile(myInputStream, destFile);

long newChecksum = FileUtils.checksum(destFile, oChecksum).getValue();

我遇到的问题是newChecksum的值与原始文件中的值不匹配。文件的大小在磁盘上匹配。有趣的是,如果我直接在终端上对这两个文件运行cksum或md5sum命令,这两个文件都是相同的。不匹配只发生在java。

这是接近它的正确方法还是有任何方法可以在提取后保留校验和值?

我也尝试过使用CheckedInputStream,但这也让我得到了与java不同的值。

编辑:这似乎与使用的Adler32对象相关(预压缩与解压缩检查)。如果我在每个文件的解压缩检查中执行“new Adler32()”而不是为所有文件重复使用相同的Adler32,我会得到正确的结果。

1 个答案:

答案 0 :(得分:1)

您是否尝试将所有文​​件连接起来?如果是,您需要确保按照“检查”它们的相同顺序阅读它们。 如果不是,则需要在计算每个文件的校验和之间调用checksum.reset()。您会注意到(在您查看源代码中)Adler32是有状态的,这意味着您在第一部分中计算文件的校验和加上所有前面的校验和。