当我试图计算一个zip文件的MD5并同时解压缩时,对于某些zip文件它不起作用:尽管文件没有损坏,但MD5总和不正确。
这是我的代码片段:
MessageDigest lMd = MessageDigest.getInstance("MD5");
FileOutputStream lFos = null;
try (DigestInputStream lDis = new DigestInputStream(lListener.getInputStream(), lMd);
ZipInputStream lZip = new ZipInputStream(lDis)) {
// Read the response content
//get the zipped file list entry
ZipEntry lZipEntry = lZip.getNextEntry();
while (lZipEntry != null) {
String lFileName = lZipEntry.getName();
File lNewFile = new File(UPDATE_FOLDER + File.separator + lFileName);
if (lZipEntry.isDirectory()) {
lNewFile.mkdirs();
} else {
//create all non exists folders
new File(lNewFile.getParent()).mkdirs();
lFos = new FileOutputStream(lNewFile);
int lRead;
while ((lRead = lZip.read(lBuffer)) > -1) {
lFos.write(lBuffer, 0, lRead);
}
lFos.close();
}
lZipEntry = lZip.getNextEntry();
}
lZip.closeEntry();
} finally {
if (lFos != null) {
lFos.close();
}
byte[] lDigest = lMd.digest();
StringBuffer lHexString = new StringBuffer();
for (int lI = 0; lI < lDigest.length; lI++) {
if ((0xFF & lDigest[lI]) < 0x10) {
lHexString.append("0"
+ Integer.toHexString((0xFF & lDigest[lI])));
} else {
lHexString.append(Integer.toHexString(0xFF & lDigest[lI]));
}
}
String lDigestStr = lHexString.toString();
你能帮助我吗?
谢谢! 前!
答案 0 :(得分:0)
您需要将这两项操作分开。 ZipInputStream
不是为完全使用基础流而构建的。原因是ZIP文件格式基本上如下所示:
<file header><file data>
<file header><file data>
<file header><file data>
<...>
<last file header><last file data>
<directory header>
<directory header>
<directory header>
<...>
<last directory header>
<file header>
和<directory header>
有不同的签名。以下是ZipInputStream
在调用getNextEntry()
时的作用:
if (get32(tmpbuf, 0) != LOCSIG) {
return null;
}
它验证它刚刚读取的缓冲区以字符“PK \ 003 \ 004”开头,这将是一个正确的文件头。但是,一旦目录标题开始,这将开始返回null
,因为目录标题是“PK \ 001 \ 002。”
在此之后,ZipInputStream
将从null
返回getNextEntry()
,之后您将停止使用它。解决您的特定问题的唯一方法是首先验证文件,然后解压缩。正如评论中所提到的,你应该这样做,因为如果验证失败,你肯定不使用该文件!