Binäres Diff / Patch für große Dateien unter Linux?


13

Ich habe zwei Partitionsimages (A und B) und möchte damit einen Patch erstellen, den ich auf A auf einem anderen Computer anwenden kann, um das neue B-Image zu erhalten, ohne das Netzwerk zu überfluten. Ich habe folgende Anforderungen:

  • funktioniert unter Linux
  • kann Unterschiede erzeugen
  • kann diffs verwenden, um Dateien zu patchen
  • kann mit Binärdateien umgehen
  • kann mit großen Dateien umgehen (einige hundert GB sollten funktionieren)
  • Keine Benutzerinteraktion erforderlich (nur eine Konsolenanwendung)
  • sollte idealerweise in der Lage sein, aus Pipes zu lesen / in Pipes zu schreiben (damit ich aus einer gzip-komprimierten Datei hineinpipen und in eine schreiben kann)

Gibt es so etwas?


Ich habe die Eingabetaste zu schnell gedrückt, als ich das Kopfgeld gestartet habe. Hier ist der Text, den ich hinzufügen wollte:
Basj

Eine Antwort mit einem leicht zu reproduzierenden Beispiel für rdiffwäre für zukünftige Referenz wertvoll. Beispiel: Nehmen wir an, file1und file2zwei ähnliche Dateien von 1 GB je. 1) Wie berechnet man den rdiff? 2) Wie speichere ich diesen rdiff in einer patchDatei? 3) Wie wende ich diese patchDatei an file1, um sie wiederherzustellen file2?
Basj

Antworten:


13

Sie sollten sich wahrscheinlich die rsync-bezogenen Tools ansehen: rdiff und rdiff-backup . Mit dem rdiffBefehl können Sie eine Patch-Datei erstellen und auf eine andere Datei anwenden.

Der rdiff-backupBefehl verwendet diesen Ansatz, um ganze Verzeichnisse zu verarbeiten, aber ich vermute, Sie arbeiten mit Single-File-Disk-Images, also rdiffwird er verwendet.


1
Was bedeuten "Signatur" und "Delta" für rdiff? Die Manpage sagt es nicht.
Tor Klingberg

1
Um meine eigene Frage zu beantworten, ist das Erstellen eines Deltas mit rdiff ein zweistufiger Prozess. Erstellen Sie zuerst eine Signaturdatei aus der alten Datei und verwenden Sie dann die Signatur und die neue Datei, um das Delta zu erstellen. Sie können zusammen mitrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg

1
@TorKlingberg Könnten Sie eine neue Antwort mit einem Beispiel posten? Sagen wir , file1und file2sind zwei ähnliche Dateien von 1 GB je. 1) Wie berechnet man den Diff? 2) Wie speichere ich diesen Diff in einer Patch-Datei? 3) Wie wende ich diese Patch-Datei an file1, um sie wiederherzustellen file2?
Basj

7

xdelta kann alles machen, was Sie wollen. Faire Warnung: Wenn Ihre Bilder nicht sehr ähnlich sind, kann dies zu einem sehr großen Patch führen, da xdelta die Hälfte des definierten Speicherpuffers verwendet, um Unterschiede zu finden. Weitere Informationen finden Sie auf der TuningMemoryBudget- Wiki-Seite. Das Erhöhen der Puffergröße kann einiges helfen.

bsdiff ist eine weitere Option, aber es ist sehr RAM-hungrig und für alles, was so groß wie ein Disk-Image ist, völlig ungeeignet.

bsdiff ist ziemlich speicherhungrig. Es erfordert max(17*n,9*n+m)+O(1)Speicherbytes, wobei ndie Größe der alten Datei und mdie Größe der neuen Datei ist. bspatch benötigt n+m+O(1)Bytes.


3

Kanonische Antwort

In Bezug auf rdiff the post ist librsync 2.0.1 eine gute Lektüre für die Erläuterung der Befehlsfunktionalität, daher habe ich unten darauf verwiesen, um den Inhalt dieser Antwort beizubehalten , wenn nichts anderes.

Es ist wichtig zu versuchen, ein gutes Verständnis der drei Schritte zum Aktualisieren einer Datei zu erlangen : Signatur , Delta und Patch, wie auf der rdiff- Manpage beschrieben. Ich habe auch ein rdiffBefehlsbeispielskript auf GitHub gefunden, das hilfreich ist und auf das ich verweisen und zitieren werde.

Im Wesentlichen...

  1. Mit einem „Start“ oder Basisdatei [ file1] und erstellen Sie eine Signaturdatei von ihm
    • Dies ist normalerweise viel kleiner als die Basis- / Originaldatei selbst
  2. Mit der Signaturdatei vergleichen Sie sie mit einer anderen Datei [ file2], die Ihrer Basisdatei ähnelt, jedoch unterschiedlich ist ( z. B. kürzlich aktualisiert wurde ), und erstellen eine Delta-Datei, die nur die Unterschiede zwischen den beiden Dateien enthält
  3. Verwenden Sie die Datei "Nur Unterschiede" oder Delta und vergleichen Sie sie mit Ihrer Basisdatei [ file1], um eine neue Datei zu generieren, die die Änderungen aus der anderen Datei [ file2] enthält, die mit den beiden übereinstimmen.

Schnellbefehle (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

Einführung

rdiff ist ein Programm zum Berechnen und Anwenden von Netzwerkdeltas. Ein rdiff-Delta ist ein Delta zwischen Binärdateien, das beschreibt, wie eine Basisdatei (oder eine alte Datei) automatisch bearbeitet werden kann, um eine Ergebnisdatei (oder eine neue Datei) zu erstellen.

Im Gegensatz zu den meisten Diff-Programmen erfordert Librsync beim Berechnen des Diff keinen Zugriff auf beide Dateien. Die Berechnung eines Deltas erfordert nur eine kurze "Signatur" der alten Datei und den vollständigen Inhalt der neuen Datei. Die Signatur enthält Prüfsummen für Blöcke der alten Datei. Mit diesen Prüfsummen findet rdiff übereinstimmende Blöcke in der neuen Datei und berechnet dann das Delta.

rdiff-Deltas sind normalerweise weniger kompakt und auch langsamer zu produzieren als xdeltas oder normale Textunterschiede. Wenn bei der Berechnung des Deltas sowohl die alten als auch die neuen Dateien vorhanden sein können, erzeugt xdelta im Allgemeinen eine viel kleinere Datei. Wenn es sich bei den verglichenen Dateien um einfachen Text handelt, ist GNU diff normalerweise die bessere Wahl, da die Unterschiede von Menschen angezeigt und als ungenaue Übereinstimmungen angewendet werden können.

rdiff kommt zur Geltung, wenn es nicht bequem ist, beide Dateien gleichzeitig zu haben. Ein Beispiel hierfür ist, dass sich die beiden Dateien auf separaten Computern befinden und Sie nur die Unterschiede übertragen möchten. Ein anderes Beispiel ist, wenn eine der Dateien auf Archiv- oder Sicherungsmedien verschoben wurde und nur ihre Signatur übrig bleibt.

Symbolisch

signature(basis-file) -> sig-file

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

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

Verwenden Sie Muster

Eine typische Anwendung des rsync-Algorithmus besteht darin, eine Datei A2 von einer Maschine A auf eine Maschine B zu übertragen, die eine ähnliche Datei A1 aufweist. Dies kann wie folgt erfolgen:

  1. B erzeugt die rdiff-Signatur von A1. Nennen Sie dies S1. B sendet die Signatur an A. (Die Signatur ist normalerweise viel kleiner als die beschriebene Datei.)
  2. A berechnet das rdiff-Delta zwischen S1 und A2. Nennen Sie dieses Delta D. A sendet das Delta an B.
  3. B wendet das Delta an, um A2 neu zu erstellen. In Fällen, in denen A1 und A2 Läufe mit identischen Bytes enthalten, sollte rdiff eine erhebliche Platzersparnis bieten.

Quelle


1
Vielen Dank!
Basj

1

JDIFF ist ein Programm, das die Unterschiede zwischen zwei (binären) Dateien ausgibt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.