我在java.util.zip
包中使用Java的ZIP存档API。我在Apache NetBeans' source repository中查看的一些代码使用以下例程计算正在读取的ZIP存档中每个条目的CRC32:
private long computeCRC32(InputStream is) throws IOException {
byte[] buf = new byte[4096];
CRC32 crc32 = new CRC32();
int read;
while ((read = is.read(buf)) != -1) {
crc32.update(buf, 0, read);
}
return crc32.getValue();
}
每个ZIP条目都会调用一次此例程:
File f = new File("a.zip");
try (ZipFile zipFile = new ZipFile(f)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
long crc;
try (InputStream is = zipFile.getInputStream(entry)) {
crc = computeCRC32(is);
}
// do something with `crc'
}
}
我想知道简单地调用ZipEntry.getCrc()(如果它返回-1以外的东西)而不是调用computeCRC32()会更好。
我担心的一个问题是,如果ZIP存档格式错误,getCrc()可能会返回不正确的值。
对于某些ZIP条目,ZipEntry.getCrc()是否可以返回除-1以外的值,而不是computeCRC32()计算的值,并且可以完全读取格式错误的ZIP存档而不会发生任何异常?
UPDATE 我使用十六进制编辑器来更改存储在测试ZIP存档的本地文件头中的CRC32。运行我的测试程序,我没有观察到异常,但是getCrc()返回了正确的CRC32而不是更改的值。
供参考,这是我的测试程序:
import java.io.*;
import java.util.*;
import java.util.zip.*;
public class ZipCrcTest {
public static void main(String[] args) throws IOException {
File f = new File("a.zip");
try (ZipFile zipFile = new ZipFile(f)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
long crc;
try (InputStream is = zipFile.getInputStream(entry)) {
crc = computeCRC32(is);
}
System.out.printf("%s %x (computed %x)\n", entry.getName(), entry.getCrc(), crc);
if (entry.getCrc() != -1L && entry.getCrc() != crc) {
System.err.printf("Crc different for %s!\n", entry.getName());
}
}
}
}
private static long computeCRC32(InputStream is) throws IOException {
byte[] buf = new byte[4096];
CRC32 crc32 = new CRC32();
int read;
while ((read = is.read(buf)) != -1) {
crc32.update(buf, 0, read);
}
return crc32.getValue();
}
}
答案 0 :(得分:0)
事实证明答案是“是”。
当我同样在ZIP存档的中央目录部分更改了zip条目CRC32的副本时,getCrc()返回了更改的值,并且没有抛出任何异常。