随机访问gzip流

13

我希望能够在gzip文件中进行随机访问。

我可以对其进行一些预处理(例如,构建某种索引),前提是预处理的结果比文件本身要小得多。

有什么建议吗?

我的想法是:

  • 对现有的gzip实现进行修改,并在每1MB压缩数据后序列化其解压缩器状态。然后,为了进行随机访问,反序列化解压缩器状态并从1MB边界读取。这似乎很困难,尤其是因为我正在使用Java,并且找不到纯Java的gzip实现 :(
  • 将文件重新分块为1MB,并进行与上述相同的操作。这种方法的缺点是需要翻倍的磁盘空间。
  • 编写一个简单的gzip格式解析器,它不执行任何解压缩操作,只检测和索引块边界(如果有任何块:我还没有阅读过gzip格式描述)。
4个回答

6

看一下这个链接(C语言代码示例)。

/* zran.c -- example of zlib/gzip stream indexing and random access
...

Gzip就是带有外壳的zlib。


1
如果您不需要跨平台部署,请查看JNA。它非常容易使用,可以作为调用C库的一种方式。 - Rex Kerr
再次感谢,我这样做了,它像魔法一样运行!Rex,也谢谢你:我使用了JNA :) - jkff
哇喔,现在我的无限大小日志查看器支持gzip压缩的日志了! - jkff

4

2
谢谢,这很不错,但我需要我的工具立即适用于现有的日志文件,它们通常由第三方压缩软件存档为.zip或.gzip格式。另外,我已经有了一个可行的解决方案 :) - jkff

1

FWIW: 我已经开发了一个命令行工具,基于zlib的zran.c源码,可以对gzip文件进行随机访问,并创建索引:https://github.com/circulosmeos/gztool

它甚至可以为正在增长的gzip文件创建索引(例如,rsyslog直接以gzip格式创建的日志文件),从而在实际中将索引创建时间减少到零。请参见-S监控)选项。


0

有趣的问题。我不明白为什么你的第二个选项(将文件分块重新压缩)会使磁盘空间翻倍。在我看来,它应该是相同的,减去一小部分开销。如果您可以控制压缩部分,那么这似乎是正确的想法。

也许你的意思是你无法控制输入,因此它会翻倍。

如果您可以这样做,我想象将其建模为一个CompressedFileStream类,该类使用一系列1mb gzip'd blob作为其后备存储。在读取时,流上的Seek()将移动到适当的blob并进行解压缩。超出blob末尾的Read()将导致流打开下一个blob。

附:GZIP在IETF RFC 1952中有描述,但它使用DEFLATE作为压缩格式。如果您按照我所想象的方式实现了这个CompressedFileStream类,那么使用GZIP说明就没有理由了。


我不喜欢第二个选项,因为我不打算删除原始文件,并且我无法控制它们的生成方式。然而,目前这就是我实际实现的方式(与你描述的相当),但我对此并不满意,这也是我提出问题的原因 :) - jkff

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