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

我坚持这个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 ,正如预期的那样。

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

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

阅读条目使用:

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

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

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

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

现在一切正常。

阅读ZipEntry的API文档 。 它说“如果知道”。 您可以使用以下内容读取内容(它只打印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); 

同样问题在这里!

ZipInputStream无法读取ZipOutputStream的输出;

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

没有可能的解释!

Archive Viewer程序打开zip文件就好了!

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

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

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

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