gpt4 book ai didi

java - 如何创建多部分 zip 文件并读回?

转载 作者:搜寻专家 更新时间:2023-10-30 19:58:45 24 4
gpt4 key购买 nike

我如何正确地将字节zipByteArrayOutputStream,然后使用ByteArrayInputStream 读取它?我有以下方法:

private byte[] getZippedBytes(final String fileName, final byte[] input) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(bos);
ZipEntry entry = new ZipEntry(fileName);
entry.setSize(input.length);
zipOut.putNextEntry(entry);
zipOut.write(input, 0, input.length);
zipOut.closeEntry();
zipOut.close();

//Turn right around and unzip what we just zipped
ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(bos.toByteArray()));

while((entry = zipIn.getNextEntry()) != null) {
assert entry.getSize() >= 0;
}

return bos.toByteArray();
}

当我执行这段代码时,底部的断言失败了,因为 entry.size-1。我不明白为什么提取的实体与压缩的实体不匹配。

最佳答案

为什么大小是 -1?

调用 getNextEntryZipInputStream只需将阅读光标放在要阅读的条目的开头。

大小(连同其他元数据)存储在实际数据的末尾,因此当光标位于开头时不容易获得。

这些信息只有在您阅读整个条目数据或转到下一个条目后才可用。

例如,转到下一个条目:

// position at the start of the first entry
entry = zipIn.getNextEntry();
ZipEntry firstEntry = entry;
// size is not yet available
System.out.println("before " + firstEntry.getSize()); // prints -1

// position at the start of the second entry
entry = zipIn.getNextEntry();
// size is now available
System.out.println("after " + firstEntry.getSize()); // prints the size

或者读取整个条目数据:

// position at the start of the first entry
entry = zipIn.getNextEntry();
// size is not yet available
System.out.println("before " + entry.getSize()); // prints -1

// read the whole entry data
while(zipIn.read() != -1);

// size is now available
System.out.println("after " + entry.getSize()); // prints the size

您的误解很常见,并且有许多关于此问题的错误报告(已关闭为“不是问题”),例如 JDK-4079029 , JDK-4113731 , JDK-6491622 .

如错误报告中所述,您可以使用 ZipFile而不是 ZipInputStream这将允许在访问条目数据之前获取大小信息;但要创建一个 ZipFile你需要一个File (请参阅构造函数)而不是字节数组。

例如:

File file = new File( "test.zip" );
ZipFile zipFile = new ZipFile(file);

Enumeration enumeration = zipFile.entries();
while (enumeration.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enumeration.nextElement();
System.out.println(zipEntry.getSize()); // prints the size
}

如何从输入流中获取数据?

如果你想检查解压缩的数据是否等于原始输入数据,你可以像这样从输入流中读取:

byte[] output = new byte[input.length];
entry = zipIn.getNextEntry();
zipIn.read(output);

System.out.println("Are they equal? " + Arrays.equals(input, output));

// and if we want the size
zipIn.getNextEntry(); // or zipIn.read();
System.out.println("and the size is " + entry.getSize());

现在 output 应该与 input 具有相同的内容。

关于java - 如何创建多部分 zip 文件并读回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41246974/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com