为什么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);
我希望这会对某人有所帮助。