代码之家  ›  专栏  ›  技术社区  ›  tangens

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

  •  6
  • tangens  · 技术社区  · 14 年前

    我被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() );
    }
    

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

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

    5 回复  |  直到 14 年前
        1
  •  4
  •   Peter Knego    14 年前

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

    要读取条目,请使用:

        byte[] buf = new byte[1024];
        int len;
        while ((len = zipIn.read(buf)) > 0) {
            // use data;
        }
    
        2
  •  1
  •   tangens    14 年前

    我自己找到了答案: entry 不包含正确的大小,但每个 zipIn.getNextEntry() 你可以从一条新的流中读取你的条目内容。所以只要把数据流读到最后,就可以得到输入的数据。

    在我的junit测试中,最后一行可能是这样的:

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

    现在一切正常。

        3
  •  1
  •   khachik    14 年前

    阅读 API doc 为了齐彭特里。上面写着“如果知道”。您可以使用以下方法读取内容(它只是打印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);
    
        4
  •  0
  •   David Antunes    14 年前

    同样的问题!

    ZipInputStream无法读取ZipOutputStream的输出;

    新的ZipFile(文件)失败,出现错误

    没有可能的解释!

    存档查看器程序可以很好地打开zip文件!

    解决方案:呃。。。它毕竟不是一个zip文件。。。 它是一个名为“folder.zip”的tar。存档查看器足够聪明。。。

    对那些有这个问题的人:再检查一遍!!!

        5
  •  0
  •   Dawid Naczke    8 年前

    最近,我在读取使用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);
    

    我希望这对某人有帮助。