ZipArchiveInputStream是从InputStream创建的,无法读取内容

时间:2013-02-21 05:40:19

标签: java apache apache-commons apache-commons-compress

工作代码:

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

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

2 个答案:

答案 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();
            }