【发布时间】:2011-04-16 06:44:02
【问题描述】:
假设file.txt.gz 有 2GB,我想查看最后 100 行左右。 zcat <file.txt.gz | tail -n 100 会经历所有这些。
我知道压缩文件不能被随机访问,如果我剪切它的最后 5MB,那么剪切后的数据将是垃圾 - 但 gzip 可以重新同步和解码流的其余部分吗?
如果我理解正确,gzip 流是描述输出内容的直接命令流 - 应该可以与之同步。然后是最近未压缩数据的 32kB 滑动窗口 - 如果我们从中间开始,它当然会作为垃圾开始,但我猜它通常会很快被真实数据填充,从那时起解压缩是微不足道的(嗯,有可能从文件开头到结尾一遍又一遍地重新复制某些内容,因此滑动窗口永远不会清除 - 如果它很常见,我会感到惊讶 - 如果发生这种情况,我们只需处理整个文件)。
我并不是非常渴望自己做这种 gzip 黑客 - 以前没有人做过,如果没有其他事情来处理损坏的文件?
或者 - 如果 gzip 真的无法做到这一点,是否还有其他与它非常相似的流压缩程序,除了它们允许在中途重新同步?
编辑:我找到了pure Ruby reimplementation of zlib 并破解了它以在滑动窗口中打印字节的年龄。事实证明,事情确实会被一遍又一遍地复制,即使在 5MB+ 之后,滑动窗口仍然包含前 100 个字节的内容,以及整个文件中随机位置的内容。
我们甚至无法通过读取前几个块和最后几个块来解决这个问题,因为这些第一个字节不是直接引用的,它只是一个非常长的副本链,并且是找出它所指内容的唯一方法是通过处理这一切。
基本上,我想要的默认选项可能是不可能的。
另一方面,zlib 有Z_FULL_FLUSH 选项,可以清除此滑动窗口以进行同步。所以问题仍然存在。假设 zlib 不时同步,是否有任何工具可以只读取它的结尾而不进行全部处理?
【问题讨论】:
-
这个问题真的和我的问题无关,
Z_FULL_FLUSH才是真正的解决方案。 -
酷!你能发布你的解决方案吗?
标签: gzip