1

工作代码:

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 读取内容。

请帮忙。请指出我哪里出错了。

4

2 回答 2

2

ZipArchiveInputStream对比ZipFile

ZipArchiveInputStream正如官方文档所述,它似乎有一些限制:

ZIP 档案按顺序存储档案条目,并在档案的最后包含所有条目的注册表。档案可以包含多个同名条目,并让注册表(称为中央目录)决定实际使用哪个条目(如果有)。

此外,ZIP 格式仅在中央目录中存储某些信息,而不是与条目本身一起存储,这是:

  • 内部和外部属性
  • 不同或额外的额外字段

这意味着在读取不可搜索的流时,ZIP 格式无法真正正确解析,这ZipArchiveInputStream 是被迫做的。因此ZipArchiveInputStream

  • 可能会返回根本不属于中央目录的条目,不应将其视为存档的一部分。
  • 可能会返回多个具有相同名称的条目。
  • 不会返回内部或外部属性。
  • 可能会返回不完整的额外字段数据。

ZipArchiveInputStream与 共享这些限制 java.util.zip.ZipInputStream

ZipFile能够首先读取中央目录并提供有关任何 ZIP 存档的正确和完整信息。

ZIP 存档知道一个称为数据描述符的功能,它是一种在条目数据之后存储条目长度的方法。只有在可以从中央目录获取大小信息或数据本身可以发出完整的信号时,这才能可靠地工作,这对于使用 DEFLATED 压缩算法压缩的数据是正确的。

ZipFile可以访问中央目录,并且可以使用数据描述符可靠地提取条目。ZipArchiveInputStream只要条目是 DEFLATED,也是如此 。对于 STORED 条目ZipArchiveInputStream,可以尝试提前读取,直到找到下一个条目,但这种方法不安全,必须由构造函数参数显式启用。

结论:

如果可能的话,你应该总是更ZipFile喜欢ZipArchiveInputStream.

我相信,ZipFile上面这句话的意思是使用InputStreamcreated using a ZipFile

InputStream is = zipFile.getInputStream(zipArchiveEntry);

于 2013-02-21T06:19:23.200 回答
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();
            }
于 2013-02-21T06:31:10.703 回答