在64位平台上获取非常大的.gz文件的文件大小

7

根据gz的规范,文件大小保存在.gz文件的最后4个字节中。

我已经创建了2个文件:

dd if=/dev/urandom of=500M bs=1024 count=500000
dd if=/dev/urandom of=5G bs=1024 count=5000000

我对它们进行了gzip压缩

gzip 500M 5G

我检查了最后4个字节

tail -c4 500M|od -I      (returns 512000000 as expected)
tail -c4 5G|od -I        (returns 825032704 as not expected)

似乎撞上了看不见的32位屏障,使写入ISIZE的值完全无意义。这比使用某些错误位更令人恼火。
有人知道一种在不解压缩的情况下从.gz文件中获取未压缩大小的方法吗?
谢谢。
规范:http://www.gzip.org/zlib/rfc-gzip.html 编辑: 如果有人想尝试,请使用/dev/zero而不是/dev/urandom。

dd seek=10G if=/dev/zero of=out.dat count=0 对于大多数文件系统来说更加方便。 - nodakai
3个回答

8

没有。

获取压缩流的确切大小的唯一方法是实际上去解压缩它(即使您将所有内容都写入/dev/null并只计算字节数)。

值得注意的是,ISIZE被定义为

ISIZE(输入大小)
这包含原始(未压缩)输入数据的大小模2^32。

在gzip RFC中,因此它实际上并没有在32位界限处“破坏”,您看到的是预期行为。


4

我没有尝试过使用您提到的大小的文件,但是我经常发现使用.gz文件时,未压缩大小为

zcat file.gz | wc -c

当我不想让未压缩的文件乱丢,或者不想再次压缩它时,可以使用管道命令将未压缩的数据传输给wc。显然,这些数据是未经压缩的。无论如何,值得一试。
编辑:当我尝试使用来自/dev/random的数据创建一个5G文件时,它生成了一个名为5G的文件,大小为5120000000字节,尽管我的文件管理器报告其大小为4.8G。
然后我用gzip 5G将其压缩,结果5G.gz的大小相同(对于随机数据没有太多压缩效果)。
然后,zcat 5G.gz | wc -c报告的大小与原始文件相同:5120000000字节。所以这个方法在这个测试中似乎可行。谢谢您的等待。

是的,谢谢。但我的问题更多地是如何在不进行解压缩的情况下获取未压缩的文件大小。对于小于32位的文件,您可以提取最后4个字节。但对于较大的文件,这是不可能的,就像您所做的那样,唯一的方法是进行解压缩。 - monkeyking
但我的方法执行了解压缩操作,不会影响原始压缩文件,也不会创建额外的未压缩文件。之后也不需要清理。值得注意的是,您接受的答案说解压缩是获得确切大小的唯一方法。打开盒子是发现里面有什么的唯一方法,这是有道理的。 - pavium
是的,它并没有影响原始文件,但我的关注点不是"不触碰"文件,而只是一个速度问题。如果我想为整个数据分配一个数组,那么我应该知道大小。这需要进行一次解压缩,然后再进行一次解压缩以进行实际数据复制。如果文件小于2.1GB,则不需要这样做。std gunzip也可以解压缩到stdout,执行以下命令: gunzip -c 文件 | wc -c但还是谢谢你的建议 :) - monkeyking
撇开所有评论不谈:如果其他方法都失败了,就采用实际的解决方案。 - Pat

0

gzip确实有一个-l选项:

       -l --list
          For each compressed file, list the following fields:

              compressed size: size of the compressed file
              uncompressed size: size of the uncompressed file
              ratio: compression ratio (0.0% if unknown)
              uncompressed_name: name of the uncompressed file

          The uncompressed size is given as -1 for files not in gzip format, such as compressed .Z files. To
          get the uncompressed size for such a file, you can use:

              zcat file.Z | wc -c

          In combination with the --verbose option, the following fields are also displayed:

              method: compression method
              crc: the 32-bit CRC of the uncompressed data
              date & time: time stamp for the uncompressed file

          The compression methods currently supported are deflate, compress, lzh (SCO compress -H) and pack.
          The crc is given as ffffffff for a file not in gzip format.

          With --name, the uncompressed name,  date and time  are those stored within the compress  file  if
          present.

          With --verbose, the size totals and compression ratio for all files is also displayed, unless some
          sizes are unknown. With --quiet, the title and totals lines are not displayed.

这个解决方案仅适用于磁盘文件,而不适用于流(原问题未指定流,所以在这方面它是一个可行的答案)。不幸的是,对于大于2 ^ 32-1字节的文件大小,未压缩的大小显示为模2 ^ 32,因此不可靠。 - Curt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接