工作代码:
InputStream is = zipFile.getInputStream(zipArchiveEntry);
BufferedReader br = new BufferedReader(new InputStreamReader(zis));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
不工作代码
InputStream is = zipFile.getInputStream(zipArchiveEntry);
ZipArchiveInputStream zis = new ZipArchiveInputStream(is);
if(zis.canReadEntryData(zipArchiveEntry)) {
// Start
BufferedReader br = new BufferedReader(new InputStreamReader(zis));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
想法不是从InputStream读取,我尝试从InputStream创建ZipArchiveInputStream,以便我可以使用canReadEntryData()方法。 canReadEntryData()完全正常。它对普通文件返回true,但我无法从ZipArchiveInputStream中读取内容。
请帮忙。请指出我哪里出错了。
答案 0 :(得分:2)
ZipArchiveInputStream
vs ZipFile
ZipArchiveInputStream
似乎有一些限制,如官方documentation所述:
ZIP存档按顺序存储存档条目并包含一个 归档文件末尾的所有条目的注册表。它是 存档可以包含多个同名条目 并让注册表(称为中央目录)决定哪个 实际上要使用的条目(如果有的话)。
此外,ZIP格式仅在内部存储某些信息 中心目录但不与条目本身一起,这是:
- 内部和外部属性
- 不同或额外的额外字段
这意味着ZIP格式无法正确解析 阅读不可搜索的流,这是
ZipArchiveInputStream
被迫做。因此ZipArchiveInputStream
- 可能会返回完全不属于中心目录的条目,不应被视为归档的一部分。
- 可能会返回多个具有相同名称的条目。
- 不会返回内部或外部属性。
- 可能会返回不完整的额外字段数据。
ZipArchiveInputStream
分享这些限制java.util.zip.ZipInputStream
。
ZipFile
能够首先读取中心目录并提供 任何ZIP档案的正确和完整信息。ZIP档案知道一种称为数据描述符的功能,这是一种方式 在条目数据之后存储条目的长度。这只能起作用 如果尺寸信息可以从中央获取,则可靠 目录或数据本身可以发出信号完整,这是事实 对于使用DEFLATED压缩算法压缩的数据。
ZipFile
可以访问中央目录并可以提取条目 可靠地使用数据描述符。同样如此ZipArchiveInputStream
只要条目是DEFLATED。对于STORED 条目ZipArchiveInputStream
可以尝试提前读取,直到找到 下一个条目,但这种方法不安全,必须启用 显式构造函数参数。
结论:
如果可能,您应该总是更喜欢
ZipFile
而不是ZipArchiveInputStream
。
我相信,ZipFile
上述句子表示使用InputStream
创建的ZipFile
:
InputStream is = zipFile.getInputStream(zipArchiveEntry);
答案 1 :(得分:1)
我认为此代码示例将帮助您使用commons compress
读取Zip ZipFile zipFile = new ZipFile("C:\\test.zip");
byte[] buf = new byte[65536];
Enumeration<?> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry zipArchiveEntry = (ZipArchiveEntry) entries.nextElement();
int n;
InputStream is = zipFile.getInputStream(zipArchiveEntry);
ZipArchiveInputStream zis = new ZipArchiveInputStream(is);
if (zis.canReadEntryData(zipArchiveEntry)) {
while ((n = is.read(buf)) != -1) {
if (n > 0) {
System.out.println(new String(buf));
}
}
}
zis.close();
}