在GZIP文件中查找文件的大小

man*_*nil 5 java gzip

有没有办法找出原始文件的大小在java中的GZIP文件中?

就像在,我有一个15 MB的文件a.txt已被GZip压缩到3GB的a.gz.我想知道a.gz中存在的a.txt的大小,而不解压缩a.gz.

Mar*_*ler 23

除了枪杀流之外,没有真正可靠的方法.您不需要保存解压缩的结果,因此您可以通过简单地读取和解码整个文件来确定大小,而不会占用解压缩结果的空间.

有一个可靠的方法来确定未压缩的大小,这是看最后四个字节gzip文件,这是进入模2的未压缩长度32在小尾数顺序.

这是不可靠的,因为a)未压缩的数据可能长于2 32个字节,并且b)gzip文件可能包含多个gzip流,在这种情况下,您只能找到最后一个流的长度.

如果您控制gzip文件的源代码,您就会知道它们由单个gzip流组成,并且您知道它们的压缩率小于2 32个字节,那么只有这样才能充满信心地使用最后四个字节.

pigz(可以在http://zlib.net/pigz/找到)可以做到这两点.pigz -l会很快给你不可靠的长度.pigz -lt将解码整个输入并为您提供可靠的长度.

  • 感谢你我刚刚发现`gzip -l bigfile.gz`实际上也使用了一种不可靠的方式O_o(因此也报告了大文件的错误压缩率). (2认同)

Cro*_*ter 5

下面是解决这个问题的一种方法——当然不是最好的方法,但是由于 Java 没有为此提供 API 方法(与处理 Zip 文件时不同),这是我能想到的唯一方法,除了其中一种方法上面的评论,讨论了最后 4 个字节的读取(假设文件大小低于 2Gb)。

GZIPInputStream zis = new GZIPInputStream(new FileInputStream(new File("myFile.gz")));
long size = 0;

while (zis.available() > 0)
{
  byte[] buf = new byte[1024];
  int read = zis.read(buf);
  if (read > 0) size += read;
}

System.out.println("File Size: " + size + "bytes");
zis.close();
Run Code Online (Sandbox Code Playgroud)

如您所见,gzip 文件被读入,读入的字节数总计表示未压缩文件的大小。

虽然这种方法确实有效,但我真的不建议将它用于非常大的文件,因为这可能需要几秒钟。(除非时间真的不是太多限制)


Pau*_*ett 0

GZIP 不会提前让您知道内容的大小。根据您的要求,我可以想到以下管理方法:

  1. 动态解压缩流,如果太大则中止
  2. 解压缩流,但不写出内容。这将得到
  3. 未压缩数据的大小,不占用任何空间。只需要读取和膨胀的处理成本
  4. 切换到使用 zip 文件(其中的条目可以提前告诉您长度)
  5. 如果您知道通常接收的数据类型,则可以根据压缩的 gzip 的大小来统计估计大小。