题
找出i java.io.InputStream
包含压缩数据的最佳方法是什么?
其他提示
<强>简介强>
由于所有答案都是5年,我觉得有责任写下今天发生的事情。我严重怀疑应该读取流的神奇字节!这是一个低级代码,一般应该避免。
简单回答
miku写道:如果可以通过ZipInputStream读取Stream,则应该压缩它。
是的,但是如果 ZipInputStream
&quot;可以读取“表示首次调用 .getNextEntry()
返回非null值。没有例外捕获等等。因此,您可以执行以下操作而不是魔术字节解析:
boolean isZipped = new ZipInputStream(yourInputStream).getNextEntry() != null;
就是这样!
一般解压缩想法
一般来说,与[stream]压缩相比,使用文件时使用文件会比使用流更方便。有几个有用的库,加上ZipFile比ZipInputStream有更多的功能。这里讨论zip文件的处理:什么是好的压缩/解压缩文件的Java库?因此,如果您可以使用文件,最好这样做!
代码示例
我的应用程序中只需要使用流。这就是我为解压缩而编写的方法:
import org.apache.commons.io.IOUtils;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public boolean unzip(InputStream inputStream, File outputFolder) throws IOException {
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry entry;
boolean isEmpty = true;
while ((entry = zis.getNextEntry()) != null) {
isEmpty = false;
File newFile = new File(outputFolder, entry.getName());
if (newFile.getParentFile().mkdirs() && !entry.isDirectory()) {
FileOutputStream fos = new FileOutputStream(newFile);
IOUtils.copy(zis, fos);
IOUtils.closeQuietly(fos);
}
}
IOUtils.closeQuietly(zis);
return !isEmpty;
}
您可以检查流的前四个字节是本地文件头签名,它启动本地文件头,继续执行ZIP文件中的每个文件,< a href =“http://www.pkware.com/documents/casestudies/APPNOTE.TXT"rel =”noreferrer“>如此处的规范所示为 50 4B 03 04
一些测试代码显示了这一点:
byte[] buffer = new byte[4];
try {
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("so.zip"));
ZipEntry ze = new ZipEntry("HelloWorld.txt");
zos.putNextEntry(ze);
zos.write("Hello world".getBytes());
zos.close();
FileInputStream is = new FileInputStream("so.zip");
is.read(buffer);
is.close();
}
catch(IOException e) {
e.printStackTrace();
}
for (byte b : buffer) {
System.out.printf("%H ",b);
}
给我这个输出:
50 4B 3 4
不是很优雅,但可靠:
如果可以通过 ZipInputStream
,应该压缩。
检查幻数可能不是正确的选择。
Docx文件也具有相似的幻数50 4B 3 4
不隶属于 StackOverflow