12

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

有什么建议吗?

我的想法是:

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

回答

6

看一看at this link(C代码的例子)。

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

Gzip只是带有信封的zlib。

+0

谢谢,这太酷了!如果我只是找到了一种方法,可以从Java中舒适地使用它.. – jkff 2010-03-26 22:04:03

+1

@jkff:如果您不需要跨平台部署,请查看JNA。作为一种调用C库的方式,这非常容易。 – 2010-03-27 01:23:36

+0

再次感谢,我这样做,它就像一个魅力!雷克斯,也感谢你:我使用JNA :) – jkff 2010-03-27 18:41:35

0

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

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

如果你可以做到这一点,我想象将它建模为一个CompressedFileStream类,该类用作其后备存储,一系列1MB gzip'd斑点。读取时,流上的Seek()会移至相应的blob并解压缩。超过blob末尾的Read()将导致流打开下一个blob。

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

+0

我不喜欢第二个选项,因为我不打算删除原始文件,并且我无法控制它们的生成方式。然而,现在这就是我实际执行的东西(正如你所描述的那样),但是我对此并不满意,这就是为什么我问这个问题:) – jkff 2010-03-26 22:00:40

3

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

(...) BGZF优于常规的gzip的优点是 BGZF允许寻求无需 通过整个文件扫描多达 位置被寻找。

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

+2

谢谢,这很好,但我需要我的工具立即适用于现有的日志文件,他们通常由第三方存档器以.zip或.gzip存档。此外,我已经有一个工作解决方案:) – jkff 2010-04-23 09:04:41