web-dev-qa-db-ja.com

Linux上の大きなファイルのバイナリ差分/パッチ?

2つのパーティションイメージ(AとB)があり、それらを使用してパッチを作成し、ネットワークをフラッディングせずに新しいBイメージを取得するために別のコンピューターのAに適用できるようにします。次の要件があります。

  • linuxで動作します
  • 差分を作成できます
  • 差分を使用してファイルにパッチを適用できます
  • バイナリファイルを処理できます
  • 大きなファイルを処理できます(数百GBが機能するはずです)
  • ユーザーの操作は必要ありません(コンソールアプリケーションのみ)
  • 理想的には、パイプからの読み取り/パイプへの書き込みができる必要があります(gzipで圧縮されたファイルからパイプにパイプして書き込みできるようにするため)

そのようなものは存在しますか?

13
thejh

おそらくrsync関連のツールを見てください:rdiffおよびrdiff-backuprdiffコマンドを使用すると、パッチファイルを作成して、他のファイルに適用できます。

rdiff-backupコマンドはこのアプローチを使用してディレクトリ全体を処理しますが、単一ファイルのディスクイメージで作業していると思いますので、rdiffを使用します。

13
njd

xdelta はあなたが望むすべてを行うことができます。ただし、画像が非常に類似していない場合、xdeltaは定義されたメモリバッファの半分を使用して差異を見つけるため、パッチが非常に大きくなる可能性があります。詳細については、 TuningMemoryBudget wikiページを参照してください。バッファサイズを増やすと、かなり役立つ場合があります。

bsdiff は別のオプションですが、veryRAMは空腹で、ディスクイメージのサイズにはまったく適していません)。

bsdiffは非常にメモリを消費します。 max(17*n,9*n+m)+O(1)バイトのメモリが必要です。ここでnは古いサイズです。 fileおよびmは新しいファイルのサイズです。 bspatchにはn+m+O(1)バイトが必要です。

7
afrazier

正準回答

rdiff 投稿に関して、 librsync 2.0.1 はコマンド機能を明確にするための良い読み物なので、他に何もない場合はこの回答の内容を保持するために以下を参照しました。

Rdiffをよく理解するようにすることが重要です ファイルを更新するための3つのステップ:signaturedelta、およびpatchrdiff manで説明したとおりページ。また、GitHubでrdiffコマンドのサンプルスクリプトを見つけました。これは、参照して引用するのに役立ちます。

基本的に...

  1. 「開始」またはベースファイル[file1]から署名ファイルを作成します
    • これは通常、ベース/元のファイル自体よりもはるかに小さい
  2. 署名ファイルを使用して、別のファイルと比較します[file2]ベースファイルと似ていますが、異なり(eg最近更新された)、デルタファイルを作成します2つのファイルの違いだけが含まれています
  3. 「差分のみ」またはデルタファイルを使用して、ベースファイルと比較します[file1]他のファイルからの変更を含む新しいファイルを生成します[file2] 2つに一致します。

クイックコマンド(per rdiff-example.sh

rdiff signature file1 signature-file            ## signature base file1
rdiff delta signature-file file2 delta-file     ## delta differences file2
rdiff patch file1 delta-file gen-file           ## compare delta to file1 to create matching file2

rdiff-example.sh

# $ rdiff --help
# Usage: rdiff [OPTIONS] signature [BASIS [SIGNATURE]]
#              [OPTIONS] delta SIGNATURE [NEWFILE [DELTA]]
#              [OPTIONS] patch BASIS [DELTA [NEWFILE]]

# Options:
#   -v, --verbose             Trace internal processing
#   -V, --version             Show program version
#   -?, --help                Show this help message
#   -s, --statistics          Show performance statistics
# Delta-encoding options:
#   -b, --block-size=BYTES    Signature block size
#   -S, --sum-size=BYTES      Set signature strength
#       --paranoia            Verify all rolling checksums
# IO options:
#   -I, --input-size=BYTES    Input buffer size
#   -O, --output-size=BYTES   Output buffer size

# create signature for old file
rdiff signature old-file signature-file
# create delta using signature file and new file
rdiff delta signature-file new-file delta-file
# generate new file using old file and delta
rdiff patch old-file delta-file gen-file
# test
diff -s gen-file new-file
# Files gen-file and new-file are identical

はじめに

rdiffは、ネットワークデルタを計算して適用するプログラムです。 rdiffデルタは、バイナリファイル間のデルタであり、基本(または古い)ファイルを自動的に編集して結果(または新しい)ファイルを生成する方法を記述します。

ほとんどのdiffプログラムとは異なり、librsyncは、diffの計算時に両方のファイルにアクセスする必要はありません。デルタを計算するには、古いファイルの短い「署名」と新しいファイルの完全な内容が必要です。署名には、古いファイルのブロックのチェックサムが含まれています。これらのチェックサムを使用して、rdiffは新しいファイル内の一致するブロックを見つけ、デルタを計算します。

rdiffデルタは通常、xdeltaや通常のテキスト差分よりもコンパクトではなく、生成も遅くなります。デルタを計算するときに古いファイルと新しいファイルの両方が存在する可能性がある場合、xdeltaは通常はるかに小さいファイルを生成します。比較されるファイルがプレーンテキストの場合、差分は人間が表示して不正確な一致として適用できるため、通常GNU diffの方が適しています。

rdiffは、両方のファイルを同時に存在させることが不便な場合に独自に機能します。この一例は、2つのファイルが別々のマシンにあり、違いのみを転送したい場合です。別の例は、ファイルの1つがアーカイブまたはバックアップメディアに移動され、その署名のみが残っている場合です。

記号

signature(basis-file) -> sig-file

delta(sig-file, new-file) -> delta-file

patch(basis-file, delta-file) -> recreated-file

パターンを使用する

Rsyncアルゴリズムの一般的なアプリケーションは、ファイルA2をマシンAから同様のファイルA1を持つマシンBに転送することです。これは次のように実行できます。

  1. BはA1のrdiff署名を生成します。これをS1と呼びます。 Bは署名をAに送信します(署名は通常、記述されているファイルよりもはるかに小さいです)。
  2. Aは、S1とA2の間のrdiffデルタを計算します。このデルタをDと呼びます。AはデルタをBに送信します。
  3. Bは、デルタを適用してA2を再作成します。 A1とA2に同じバイトの実行が含まれている場合、rdiffを使用すると大幅にスペースを節約できます。

ソース

3
Pimp Juice IT

[〜#〜] jdiff [〜#〜] は、2つの(バイナリ)ファイルの違いを出力するプログラムです。

1
totti