6

这可能属于“不太可行”或“不值得付出努力”的范畴,但在这里。

我正在尝试随机访问存储在多部分 gzip 文件中的记录。具体来说,我感兴趣的文件是压缩的Heretrix Arc 文件。(如果您不熟悉多部分 gzip 文件,gzip 规范允许将多个 gzip 流连接到一个 gzip 文件中。它们不共享任何字典信息,它是简单的二进制附加。)

我认为应该可以通过在文件中寻找某个偏移量来做到这一点,然后扫描 gzip 魔术头字节(即 0x1f8b,根据RFC),并尝试从以下字节读取 gzip 流. 这种方法的问题在于,这些相同的字节也可能出现在实际数据中,因此寻找这些字节可能会导致开始读取 gzip 流的位置无效。鉴于记录偏移量不是先验已知的,是否有更好的方法来处理随机访问?

4

2 回答 2

3

与 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:03:43.777 回答
1

如您所见,GZIP 的设计对随机访问并不友好。

您可以按照您的描述进行操作,然后如果您在解压缩器中遇到错误,则可以断定您找到的签名实际上是压缩数据。
如果你解压完成了,那么就很容易通过CRC32验证刚刚解压的流的有效性。

如果文件不是很大,你可以考虑将所有条目依次解压缩,并保留签名的偏移量以建立一个目录。解压缩时,将字节转储到位桶。此时您将生成一个目录,然后您可以支持基于文件名、日期或其他元数据的随机访问。

对于 100k 以下的文件,这将是相当快的。就像猜测一样,如果您有 10 个文件,每个文件大约 100k,那么在现代 CPU 上可能会在 2 秒内完成。这就是我所说的“相当快”。但只有您知道您的应用程序的性能要求。

你有一个 GZipInputStream 类吗?如果是这样,你就成功了一半。

于 2009-08-04T01:53:12.603 回答