13

gzip で圧縮されたファイルにランダム アクセスできるようにしたいと考えています。前処理の結果がファイル自体よりもはるかに小さい場合は、前処理を行う余裕があります (たとえば、ある種のインデックスを作成します)。

何かアドバイス?

私の考えは次のとおりです。

  • 既存の gzip 実装をハックし、圧縮データの 1 メガバイトごとにデコンプレッサの状態をシリアル化します。次に、ランダム アクセスを行うために、デコンプレッサの状態を逆シリアル化し、メガバイト境界から読み取ります。特に私はJavaで作業していて、純粋なJava gzip実装を見つけることができなかったので、これは難しいようです:(
  • ファイルを 1Mb 単位で再圧縮し、上記と同じ操作を行います。これには、必要なディスク容量が 2 倍になるという欠点があります。
  • 解凍を行わず、ブロック境界を検出してインデックスを付けるだけの 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

The BGZF file format, compatible with GZIP was developped by the biologists.

(...) The advantage of BGZF over conventional gzip is that BGZF allows for seeking without having to scan through the entire file up to the position being sought.

In http://picard.svn.sourceforge.net/viewvc/picard/trunk/src/java/net/sf/samtools/util/ , have a look at BlockCompressedOutputStream and BlockCompressedInputStream.java

于 2010-04-22T10:02:41.673 に答える
0

興味深い質問です。2番目のオプション(ファイルをチャンクで再圧縮する)がディスク容量を2倍にする理由がわかりません。私には同じで、少量のオーバーヘッドが少ないようです。圧縮部分を制御できる場合、それは正しい考えのようです。

おそらく、入力を制御できないため、入力が2倍になるということです。

あなたがそれを行うことができれば、一連の 1 MB の gzip された blob をバッキング ストアとして使用する CompressedFileStream クラスとしてモデル化することを想像しています。読み取り時、ストリームの Seek() は適切なブロブに移動して解凍します。ブロブの終わりを過ぎた Read() により、ストリームは次のブロブを開きます。

ps: GZIP はIETF RFC 1952に記載されていますが、圧縮形式にDEFLATEを使用します。私が想像したように、この CompressedFileStream クラスを実装した場合、GZIP の詳細を使用する理由はありません。

于 2010-03-26T21:51:36.557 に答える