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


13

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

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

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


バウンティを開始するときにEnterキーを速く押しすぎました。これが私が追加したかったテキストです:
Basj

の再現しやすい例を使用した回答は、rdiff将来の参照に役立つでしょう。例:それぞれ1GBの2つの類似したファイルであるfile1としましょうfile2。1)rdiffの計算方法は?2)このrdiffをpatchファイルに保存する方法は?3)このpatchファイルを適用しfile1て回復するにはどうすればよいfile2ですか?
Basj

回答:


13

おそらく、rsync関連のツールであるrdiffrdiff-backup確認する必要があります。このrdiffコマンドを使用すると、パッチファイルを作成して他のファイルに適用できます。

rdiff-backupコマンドは、ディレクトリ全体に対処するため、このアプローチを使用していますが、私はあなたが単一ファイルのディスクイメージで作業している推測しているので、rdiff使用する1つになります。


1
「署名」と「デルタ」はrdiffに対して何を意味しますか?マニュアルページには書かれていません。
Tor Klingberg 2016

1
私自身の質問に答えるために、rdiffを使用してデルタを作成することは、2ステップのプロセスです。最初に古いファイルから署名ファイルを作成し、次に署名と新しいファイルを使用してデルタを作成します。彼らは一緒に実行することができますrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg '13 / 09/13

1
@TorKlingberg例を挙げて新しい回答を投稿できますか?たとえばfile1file2それぞれ1 GBの2つの類似したファイルであるとします。1)差分の計算方法は?2)この差分をパッチファイルに保存する方法 3)このパッチファイルを適用しfile1て回復するにはどうすればよいfile2ですか?
Basj

7

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

bsdiffは別のオプションですが、RAMを非常に消費するため、ディスクイメージのサイズにはまったく適していません。

bsdiffはメモリを大量に消費します。max(17*n,9*n+m)+O(1)メモリのバイト数が必要です。はn古いファイルmのサイズで、は新しいファイルのサイズです。bspatchにn+m+O(1)バイトが必要です。


3

正解

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

rdiffの manページで説明されているように、ファイルを更新するためのrdiffの3つのステップ(署名デルタパッチ)をよく理解することは重要です。また、GitHubで、参考にして引用するのに役立つコマンドのサンプルスクリプトを見つけました。rdiff

本質的に...

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

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

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

rdiffは、両方のファイルを同時に存在させることが不都合な場合に役立ちます。この1つの例は、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は大幅なスペース節約を提供します。

ソース


1
どうもありがとうございました!
Basj

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.