13

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

有什么建议吗?

我的想法是:

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

4 回答 4

6

看看这个链接(C 代码示例)。

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

Gzip 只是带有信封的 zlib。

于 2010-03-26T21:46:51.970 回答
4

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

(...) BGZF 与传统 gzip 相比的优势在于 BGZF 允许搜索,而无需扫描整个文件直到搜索的位置。

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

于 2010-04-22T10:02:41.673 回答
1

FWIW:我在zlib 的zran.c源代码上开发了一个命令行工具,它可以通过为 gzip 文件创建索引来随机访问 gzip:https ://github.com/circulosmeos/gztool

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

于 2019-07-24T21:19:39.853 回答
0

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

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

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

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

于 2010-03-26T21:51:36.557 回答