随机访问 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 流的主要内容,如果未能解决你的问题,请参考以下文章