随机访问 gzip 流

Posted

技术标签:

【中文标题】随机访问 gzip 流【英文标题】:Random access gzip stream 【发布时间】:2010-03-26 21:39:33 【问题描述】:

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

有什么建议吗?

我的想法是:

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

【问题讨论】:

【参考方案1】:

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

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

Gzip 只是带有信封的 zlib。

【讨论】:

@jkff:如果您不需要跨平台部署,请查看 JNA。作为调用 C 库的一种方式,它非常容易使用。 再次感谢,我这样做了,它就像一个魅力!雷克斯,也谢谢你:我使用了 JNA :) 哇哦,现在我的无限大小日志查看器支持 gzip 日志!【参考方案2】:

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

(...) 的优点 BGZF 优于传统 gzip 是 BGZF 允许寻找而无需 扫描整个文件直到 正在寻找的职位。

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

【讨论】:

谢谢,这很好,但我需要我的工具立即适用于现有的日志文件,并且它们通常由第三方存档器以 .zip 或 .gzip 存档。此外,我已经有了一个可行的解决方案:)【参考方案3】:

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

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

【讨论】:

【参考方案4】:

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

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

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

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

【讨论】:

我不喜欢第二个选项,因为我不会删除原始文件,而且我无法控制它们的生成方式。但是,现在这就是我实际实现这些东西的方式(就像你描述的那样),但我对此并不满意,这就是我问这个问题的原因:)

以上是关于随机访问 gzip 流的主要内容,如果未能解决你的问题,请参考以下文章

详解 随机访问流

IO---随机访问文件流

《七》随机访问文件流

java 21 - 12 随机访问流(不属于IO流)

黑马程序员——————> 随机访问流

Java基础-IO流对象之随机访问文件(RandomAccessFile)