检测流是否使用Java压缩的最佳方法

Fed*_*rne 19 java zip inputstream

找出java.io.InputStream包含压缩数据的最佳方法是什么?

Inn*_*nty 38

介绍

由于所有答案都是5年,我觉得有责任写下来,今天发生了什么.我严重怀疑应该读取流的神奇字节!这是一个低级代码,一般应该避免.

简单回答

miku写道:

如果可以通过ZipInputStream读取Stream,则应该压缩它.

是的,但是在ZipInputStream"可以读取"的情况下意味着第一次调用.getNextEntry()返回非空值.没有例外捕获等等.因此,您可以执行以下操作,而不是魔术字节解析:

boolean isZipped = new ZipInputStream(yourInputStream).getNextEntry() != null;
Run Code Online (Sandbox Code Playgroud)

就是这样!

一般解压思路

一般来说,与[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;
}
Run Code Online (Sandbox Code Playgroud)

  • 是的。我找到了一个解决方案:在将 inputStream 传递给 ZipInputStream 之前用 BufferedInputStream 包装它,这样你就可以调用 mark() 和 reset() 了。/sf/answers/3713352401/ (2认同)

McD*_*ell 22

ZIP格式的神奇字节50 4B.您可以测试流(使用标记重置 - 您可能需要缓冲)但我不希望这是100%可靠的方法.没有办法将它与以字母开头的US-ASCII编码文本文件区分开来PK.

最好的办法是打开流之前提供的内容格式,元数据,然后进行适当处理.


Dav*_*ebb 6

你可以检查前四个字节流的是本地文件头标识启动的本地文件头是进行中的每个文件的ZIP文件,如图所示规格这里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);
}
Run Code Online (Sandbox Code Playgroud)

给我这个输出:

50 4B 3 4 
Run Code Online (Sandbox Code Playgroud)


mik*_*iku 5

不是很优雅,但可靠:

如果可以通过读取流ZipInputStream,则应该压缩.

  • @fedearne:拉链流是否是损坏的拉链流? (10认同)
  • 我同意:如果ZipInputStream无法读取它,那么它"意味着"是一个Zip文件并不重要*.对? (2认同)
  • 这是最可靠的选择.如果它已损坏,你怎么知道它是ZIP?你只需要猜一猜. (2认同)