为什么ZipInputStream无法读取ZipOutputStream的输出?

时间:2010-11-12 21:49:23

标签: java zip

我坚持这个junit测试:

public void test() throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ZipOutputStream zipOut = new ZipOutputStream( out );
    zipOut.putNextEntry( new ZipEntry( "file" ) );
    zipOut.write( (new byte[] { 0x01, 0x02, 0x03 }) );
    zipOut.closeEntry();
    zipOut.close();

    ZipInputStream zipIn = new ZipInputStream( new ByteArrayInputStream( out.toByteArray() ) );
    ZipEntry entry = zipIn.getNextEntry();
    assertNotNull( entry );
    assertEquals( "file", entry.getName() );
    assertEquals( 3, entry.getSize() );
}

我正在写一个名为“file”的文件和一个ZipOutputStream的三个字节的内容。然后我尝试用ZipInputStream读取创建的数据,但最后一个断言失败,因为entry.getSize()-1而不是3,正如预期的那样。

我在这里做错了什么?我需要更改什么才能恢复“文件”的内容?我想,我首先要知道能够从流中读取数据的长度吗?

5 个答案:

答案 0 :(得分:3)

您实际上必须阅读条目的内容,然后entry.getSize()将返回正确的大小。

阅读条目使用:

    byte[] buf = new byte[1024];
    int len;
    while ((len = zipIn.read(buf)) > 0) {
        // use data;
    }

答案 1 :(得分:1)

我自己找到了答案:entry不包含正确的尺寸,但每个zipIn.getNextEntry()都会获得一个新的流来阅读您的条目内容。因此,只需阅读流到最后,您就可以获得条目的数据。

在我的junit测试中,最后一行可能如下所示:

byte[] restoredContent = new byte[ 10 ];
assertEquals( 3, zipIn.read( restoredContent ) );

现在一切正常。

答案 2 :(得分:1)

阅读API doc以获取ZipEntry。它说“如果知道”。您可以使用以下内容读取内容(它只打印zipentry的大小,适当地更改它的过程数据):

ZipEntry entry = zipIn.getNextEntry();
int BUFSIZE = 1024;
byte [] buffer = new byte[BUFSIZE];
int read = 0;
int total = 0;
while( (read = zipIn.read(buffer, 0, BUFSIZE)) >0 ) { 
  total += read;
  // what do you want to do with the data read? Do it here
}   
System.err.println("Total: " + total);

答案 3 :(得分:0)

这里有同样的问题!

ZipInputStream无法读取ZipOutputStream的输出;

新ZipFile(文件)失败并显示错误

没有可能的解释!

归档查看器程序打开zip文件就好了!

解决方案:呃......毕竟它不是一个zip文件...... 这是一个名为'folder.zip'的焦油。档案查看器足够聪明......

对于有这个问题的人:仔细检查!!!

答案 4 :(得分:0)

最近我在读取使用ZipOutputStream创建的zip字节时遇到了类似的问题。

以下代码段导致了java.lang.NegativeArraySizeException。

zipEntry = zipInputStream.getNextEntry();
byte[] bytes = new byte[(int) zipEntry.getSize()];

快速解决方案是使用Apache commons-io IOUtils来读取当前条目的所有字节。

zipEntry = zipInputStream.getNextEntry();
byte[] bytes = org.apache.commons.io.IOUtils.toByteArray(zipInputStream);

我希望这会对某人有所帮助。