我坚持这个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
,正如预期的那样。
我在这里做错了什么?我需要更改什么才能恢复“文件”的内容?我想,我首先要知道能够从流中读取数据的长度吗?
答案 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);
我希望这会对某人有所帮助。