随机访问 gzip 流
-
22-09-2019 - |
题
我希望能够随机访问 gzip 压缩文件。我可以对其进行一些预处理(例如,构建某种索引),前提是预处理的结果比文件本身小得多。
有什么建议吗?
我的想法是:
- 对现有的 gzip 实现进行攻击,并序列化其解压缩器状态,例如每 1 MB 的压缩数据。然后进行随机访问,反序列化解压缩器状态并从兆字节边界读取。这看起来很难,特别是因为我正在使用 Java 并且我找不到纯 java gzip 实现:(
- 将文件重新压缩为 1Mb 块,并执行与上述相同的操作。这样做的缺点是所需的磁盘空间加倍。
- 编写一个简单的 gzip 格式解析器,它不执行任何解压缩,仅检测和索引块边界(如果甚至有任何块:我还没有阅读gzip格式说明)
解决方案
看一看 在这个链接 (C 代码示例)。
/* zran.c -- example of zlib/gzip stream indexing and random access
...
Gzip 只是带有信封的 zlib。
其他提示
这 BGZF 与 GZIP 兼容的文件格式是由生物学家开发的。
(...)BGZF比常规GZIP的优点是,BGZF允许在不必扫描整个文件之前寻求到所寻求的位置。
在 http://picard.svn.sourceforge.net/viewvc/picard/trunk/src/java/net/sf/samtools/util/ ,看看BlockCompressedOutputStream和BlockCompressedInputStream.java
有趣的问题。我不明白为什么你的第二个选项(重新压缩文件块)会使磁盘空间增加一倍。在我看来,情况是一样的,只是减少了少量的开销。如果您可以控制压缩件,那么这似乎是正确的想法。
也许你的意思是你无法控制输入,因此它会加倍。
如果你能做到的话,我想象将它建模为一个 CompressedFileStream 类,该类使用一系列 1mb gzip'd blob 作为其后备存储。读取时,流上的 Seek() 将移动到适当的 blob 并解压缩。超过 blob 末尾的 Read() 将导致流打开下一个 blob。
附:GZIP 的描述见 IETF RFC 1952, ,但它使用 放气 对于压缩格式。如果您按照我的想象实现了这个 CompressedFileStream 类,那么就没有理由使用 GZIP 阐述。
前言:我开发了一个命令行工具 兹利布的 兹然网 源代码 它为 gzip 文件创建索引: https://github.com/circulosmeos/gztool
它甚至可以为仍在增长的 gzip 文件创建索引 (例如 rsyslog 直接以 gzip 格式创建的日志),从而在实践中减少索引创建时间为零。请参阅 -S
(监督) 选项。