フィールドの1つでソートされた通常の固定幅ファイルがあると仮定します。レコードの長さがわかっているので、lseekを使用してバイナリ検索を実装し、ファイル全体を読み取ることなく、指定された値に一致するフィールドを持つレコードを見つけることができます。
ここでの問題は、ファイルがgzipで圧縮されていることです。ファイルを完全に膨らませることなくこれを行うことは可能ですか?gzipを使用しない場合。この種の動作をサポートする圧縮はありますか?
フィールドの1つでソートされた通常の固定幅ファイルがあると仮定します。レコードの長さがわかっているので、lseekを使用してバイナリ検索を実装し、ファイル全体を読み取ることなく、指定された値に一致するフィールドを持つレコードを見つけることができます。
ここでの問題は、ファイルがgzipで圧縮されていることです。ファイルを完全に膨らませることなくこれを行うことは可能ですか?gzipを使用しない場合。この種の動作をサポートする圧縮はありますか?
bzip2 ファイル形式は、個別に圧縮された複数のブロックで構成されています。bzip2 ファイルと一緒にインデックスを維持したい場合は、lseek の場所を知ることができます。
注:これは質問の複製です:
これらは同じ質問に答えますが、圧縮状態をリセットするために同期ポイントが挿入された gzip 互換の出力形式として BGZF を識別します。
これは、zip および派生物で圧縮されたファイルではまったく不可能です。これらはローリング ディクショナリ ウィンドウに基づいており、通常、出力コードの最上位ビットをバッファベースで圧縮します。要するに、zip ファイル内の特定のバイト シーケンスは、コンテキストがなければ意味がないということです。
圧縮ファイルから特定のレコードをランダムに読み取れるようにする場合は、各レコードを個別に圧縮してから、ファイルにインデックスを作成する必要があります。データによっては、これにより圧縮ステップが無駄になる可能性があります。
私が知っているほとんどすべての圧縮アルゴリズムはブロック モードで動作します。つまり、ランダム シークは不可能です。初期辞書を使用しない LZMA でさえ、順次解凍が必要です。
ストリーム圧縮とは、通常、状態をリセットする (または実際にブロックに分割する) いくつかのキーを使用した、適応型非可逆圧縮を意味します。詳細はより複雑です。
これを解決するためのいくつかのアイデアを次に示します。
最後の方法は小さな圧縮ファイルに適しており、block メソッドは大きな圧縮ファイルに適しています。2 つを混在させることができます。
PS: 入力で修正されましたが、圧縮ファイルが修正されるという意味ではありません。というわけで、あまり役に立たない情報です。
Liudvikas Bukysの言葉を続ける:圧縮されたブロックに一意のヘッダーがある場合は、インデックスは必要ありません。これは、一部の圧縮ビデオ形式でのシークが行われる方法と似ています。ポイントを探して、次のヘッダーを探します。ただし、誤認が発生する可能性があるため、これには(チェックサムを使用した)堅牢な検証が必要です。
必要なのはシーク可能な圧縮です。dictサーバーには、ヘッダーのgzip拡張子にシーク可能であるため、gzipとフォーマット互換性のあるdictzipがあり、sleuthキットには、各ブロックの先頭にブロック長を格納するため、そうではないsgzipがあります。
Wernight の発言に基づいて、gzip する前に、ファイルを多くの固定サイズのサブファイルに分割できます。バイナリ検索は、範囲を含むサブファイルを検索することから開始できます。その後、全体ではなく小さなサブファイルを解凍するだけで済みます。各サブファイルの最初の行を含む上位レベルのファイルをアーカイブに作成することで最適化できます。