【问题标题】:Reading last lines of gzipped text file读取 gzip 压缩文本文件的最后几行
【发布时间】: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 不时同步,是否有任何工具可以只读取它的结尾而不进行全部处理?

【问题讨论】:

标签: gzip


【解决方案1】:

Z_FULL_FLUSH 发出可用于同步的已知字节序列 (00 00 FF FF)。 This link 可能有用。

【讨论】:

    【解决方案2】:

    这是块密码和流密码之间的区别。因为 gzip 是一种流密码,所以您可能需要整个文件直到某个点才能解密该点的字节。

    正如你所提到的,当窗户被清理干净时,你就是金色的。但是不能保证 zlib 确实经常为您执行此操作...我建议您从文件末尾向后查找并找到完全刷新的标记。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-12
      • 2021-11-06
      • 2012-05-20
      • 1970-01-01
      • 2014-07-04
      • 2020-12-31
      • 2010-10-12
      • 1970-01-01
      相关资源
      最近更新 更多