随机访问gzip流

时间:2010-03-26 21:39:34

标签: language-agnostic compression gzip large-files random-access

我希望能够随机访问gzip压缩文件。 我可以负担得起对它进行一些预处理(比如构建某种索引),只要预处理的结果比文件本身小得多。

有什么建议吗?

我的想法是:

  • 破解现有的gzip实现并将其解压缩器状态序列化,例如1兆字节的压缩数据。然后进行随机访问,反序列化解压缩器状态并从兆字节边界读取。这看起来很难,特别是因为我正在使用Java而我找不到纯java gzip实现:(
  • 以1Mb的块重新压缩文件并执行与上面相同的操作。这样做的缺点是所需的磁盘空间加倍。
  • 编写一个gzip格式的简单解析器,它不进行任何解压缩,只检测和索引块边界(如果有任何块:我还没有读过gzip格式描述)

4 个答案:

答案 0 :(得分:6)

看看at this link(C代码示例)。

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

Gzip只是带信封的zlib。

答案 1 :(得分:4)

与GZIP兼容的 BGZF 文件格式由生物学家开发。

  

(...)的优势   BGZF胜过传统的gzip就是这样   BGZF允许在没有的情况下进行搜索   扫描整个文件到   正在寻找的位置。

http://picard.svn.sourceforge.net/viewvc/picard/trunk/src/java/net/sf/samtools/util/中,看一下BlockCompressedOutputStream和BlockCompressedInputStream.java

答案 2 :(得分:0)

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

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

如果你能做到这一点,我想象它将它建模为一个CompressedFileStream类,它使用一系列1mb gzip的blob作为它的后备存储。在读取时,流上的Seek()将移动到适当的blob并解压缩。超过blob末尾的Read()将导致流打开下一个blob。

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

答案 3 :(得分:0)

FWIW:我在Difference in boto3 between resource, client, and session?上开发了一个命令行工具,该工具可为gzip文件创建索引:zlib's zran.c source code

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