4

7zip で圧縮された非常に巨大なファイルにランダム アクセス (多くのシーク) を行うことは可能ですか?

元のファイルは非常に巨大 (999 GB xml) で、解凍した形式で保存することはできません (あまり空き容量がありません)。したがって、7z 形式で、選択したブロックより前のすべてのブロックを解凍せずに中間ブロックにアクセスできる場合、ブロックの開始と対応する元のファイル オフセットのインデックスを作成できます。

私の7zアーカイブのヘッダーは

37 7A BC AF 27 1C 00 02 28 99 F1 9D 4A 46 D7 EA  // 7z archive version 2;crc; n.hfr offset
00 00 00 00 44 00 00 00 00 00 00 00 F4 56 CF 92  // n.hdr offset; n.hdr size=44. crc
00 1E 1B 48 A6 5B 0A 5A 5D DF 57 D8 58 1E E1 5F
71 BB C0 2D BD BF 5A 7C A2 B1 C7 AA B8 D0 F5 26
FD 09 33 6C 05 1E DF 71 C6 C5 BD C0 04 3A B6 29

更新: 7z アーカイバーは、このファイルには LZMA アルゴリズムで圧縮された単一のデータ ブロックがあると述べています。テストでの解凍速度は 600 MB/秒 (解凍されたデータの) で、1 つの CPU コアのみが使用されます。

4

4 に答える 4

2

技術的には可能ですが、「現在利用可能なバイナリ 7zip コマンド ライン ツールでそれが可能ですか」という質問に対しては、残念ながら答えはノーです。可能な最善の方法は、各ファイルをアーカイブに個別に圧縮し、ファイルを直接取得できるようにすることです。 . しかし、圧縮したいのは単一の (巨大な) ファイルであるため、このトリックは機能しません。

ファイルを小さなブロックに分割し、LZMA エンコーダー (LZMA SDK に含まれています) にフィードするしか方法はありません。残念ながら、それにはある程度のプログラミングスキルが必要です。

注 : 技術的には劣るものの、単純な圧縮アルゴリズムがここにあります。メイン プログラムはまさにあなたが探していることを実行します。ソース ファイルを小さなブロックに分割し、それらを 1 つずつコンプレッサー (この場合は LZ4) に送ります。次に、デコーダは逆の操作を行います。すべての圧縮ブロックを簡単にスキップして、取得したいブロックに直接進むことができます。 http://code.google.com/p/lz4/source/browse/trunk/lz4demo.c

于 2011-10-25T12:10:25.850 に答える
1

7z アーカイバによると、このファイルには LZMA アルゴリズムで圧縮された単一のデータ ブロックが含まれています。

単一の圧縮ブロックかどうかを確認するための 7z / xz コマンドは何でしたか? 複数のスレッドで使用すると、7z はマルチブロック (マルチストリーム) アーカイブを作成しますか?

元のファイルは非常に巨大です (999gb xml)

朗報: ウィキペディアは、ダンプのマルチストリーム アーカイブに切り替えました (少なくとも enwiki の場合): http://dumps.wikimedia.org/enwiki/

たとえば、最新のダンプhttp://dumps.wikimedia.org/enwiki/20140502/にはマルチストリーム bzip2 (別のインデックス「offset:export_article_id:article_name」を使用) があり、7z ダンプは多くのサブ GB アーカイブに保存されています。アーカイブごとに ~3,000 (?) 件の記事:

複数の bz2 ストリームの記事、テンプレート、メディア/ファイルの説明、およびプライマリ メタページ、ストリームごとに 100 ページ

enwiki-20140502-pages-articles-multistream.xml.bz2 10.8 GB
enwiki-20140502-pages-articles-multistream-index.txt.bz2 150.3 MB

完全な編集履歴のあるすべてのページ (.7z)

enwiki-20140502-pages-meta-history1.xml-p000000010p000003263.7z 213.3 MB
enwiki-20140502-pages-meta-history1.xml-p000003264p000005405.7z 194.5 MB
enwiki-20140502-pages-meta-history1.xml-p000005406p000008209.7z 216.1 MB
enwiki-20140502-pages-meta-history1.xml-p000008210p000010000.7z 158.3 MB
enwiki-20140502-pages-meta-history2.xml-p000010001p000012717.7z 211.7 MB
 .....
enwiki-20140502-pages-meta-history27.xml-p041211418p042648840.7z 808.6 MB

7z ダンプの場合でも、bzip2 インデックスを使用して記事 ID を推定できると思います。必要なのは、正しい範囲 (..p first_id p last_id .7z) の 7z アーカイブだけです。stub-meta-history.xmlも役立つかもしれません。

ダンプに関する FAQ: http://meta.wikimedia.org/wiki/Data_dumps/FAQ

于 2014-06-05T12:03:10.797 に答える
1

これはどう:

概念: 基本的に 1 つのファイルのみを読み取るため、.7z をブロックごとにインデックス付けします。

圧縮ファイルをブロックごとに読み取り、各ブロックに番号と、場合によっては大きなファイル内のオフセットを与えます。データ ストリーム内のターゲット アイテム アンカーをスキャンします (例: ウィキペディアの記事のタイトル)。アンカーレコードごとに、項目が開始されたブロック番号を保存します (それはおそらく前のブロックにありました)。

ある種の O(log n) ストアにインデックスを書き込みます。アクセスの場合は、ブロック番号とそのオフセットを取得し、ブロックを抽出してアイテムを見つけます。コストは、1 つのブロック (またはごく少数) の抽出と、そのブロック内の文字列検索に限定されます。

このためには、ファイルを 1 回読み取る必要がありますが、ストリーミングして処理後に破棄できるため、ディスクには何もヒットしません。

DARN: あなたは基本的にあなたの質問でこれを仮定しました...答える前に質問を読む方が有利だと思われます...

于 2011-10-25T16:09:19.787 に答える
1

のみ使用:

7z e myfile_xml.7z -so | sed [something] 

7 行目を取得する例:

7z e myfile_xml.7z -so | sed -n 7p

于 2019-02-03T08:46:24.047 に答える