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

时间:2012-03-15 06:40:06

标签: java gzip

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

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

4 个答案:

答案 0 :(得分:22)

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

有一种不可靠的方法来确定未压缩的大小,即查看gzip文件的最后四个字节,这是以小端顺序模2 32 的条目的未压缩长度

这是不可靠的,因为a)未压缩的数据可能长于2 32 字节,而b)gzip文件可能包含多个gzip流,在这种情况下你会发现只有长度这些流中的最后一个。

如果您控制gzip文件的源代码,您就会知道它们由单个gzip流组成,并且您知道它们的压缩率小于2 32 字节,然后才会你可以放心地使用最后四个字节。

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

答案 1 :(得分:4)

下面是针对此问题的一种方法 - 当然不是最好的方法,但是由于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();

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

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

答案 2 :(得分:2)

public class ReadStream {

    public static void main(String[] args) {
        try {
            RandomAccessFile raf = new RandomAccessFile(new File("D:/temp/temp.gz"), "r");
            try {
                raf.seek(raf.length() - 4);

                int b4 = raf.read();
                int b3 = raf.read();
                int b2 = raf.read();
                int b1 = raf.read();
                int val = (b1 << 24) | (b2 << 16) + (b3 << 8) + b4;

                System.out.println(val);

                raf.close();
            } catch (IOException ex) {
                Logger.getLogger(ReadStream.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ReadStream.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

答案 3 :(得分:0)

GZIP不会提前告知您内容的大小。根据您的要求,这些是我可以想到的管理方式:

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