Binarny plik różnicowy / łatka dla dużych plików w systemie Linux?

13

Mam dwa obrazy partycji (A i B) i chcę ich użyć do utworzenia poprawki, którą mogę zastosować na A na innym komputerze, aby uzyskać nowy obraz B bez zalewania sieci. Mam następujące wymagania:

  • działa w systemie Linux
  • może tworzyć różnice
  • może używać diffs do łatania plików
  • obsługuje pliki binarne
  • może obsługiwać duże pliki (powinno działać kilkaset GB)
  • nie wymaga interakcji użytkownika (tylko aplikacja konsoli)
  • idealnie, powinienem być w stanie czytać z / zapisywać do potoków (tak, że mogę do niego pobierać z pliku skompresowanego gzip i zapisywać do jednego)

Czy coś takiego istnieje?

thejh
źródło
Zbyt szybko nacisnąłem klawisz Enter podczas rozpoczynania nagrody. Oto tekst, który chciałem dodać:
Basj
Odpowiedź z łatwym do odtworzenia przykładem rdiffbyłaby cenna do wykorzystania w przyszłości. Przykład: powiedzmy Miejmy file1a file2są dwa podobne pliki 1GB każdy. 1) Jak obliczyć rdiff? 2) Jak zapisać ten patchplik rdiff w pliku? 3) Jak zastosować ten patchplik file1do odzyskania file2?
Basj

Odpowiedzi:

13

Prawdopodobnie powinieneś rzucić okiem na narzędzia związane z rsync: rdiff i rdiff-backup . rdiffKomenda pozwala produkować plik poprawki i stosować go do innego pliku.

rdiff-backupKomenda używa tego podejścia do czynienia z całych katalogów, ale zgaduję, że pracujesz z obrazów dysków pojedynczych plików, tak rdiffbędzie z nich korzystać.

njd
źródło
1
Co oznacza „podpis” i „delta” dla rdiff? Strona podręcznika nie mówi.
Tor Klingberg
1
Aby odpowiedzieć na moje pytanie, tworzenie delty za pomocą rdiff jest procesem dwuetapowym. Najpierw utwórz plik podpisu ze starego pliku, a następnie użyj podpisu i nowego pliku, aby utworzyć różnicę. Można je uruchomić razem zrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg
1
@TorKlingberg Czy możesz zamieścić nową odpowiedź z przykładem? Powiedzmy, file1i file2są dwa podobne pliki 1GB każdy. 1) Jak obliczyć różnicę? 2) Jak zapisać ten plik różnicowy w pliku łatki? 3) Jak zastosować ten plik łatki file1do odzyskania file2?
Basj
7

xdelta może zrobić wszystko, co chcesz. Ostre ostrzeżenie, jeśli twoje obrazy nie są bardzo podobne, możesz skończyć z bardzo dużą łatką, ponieważ xdelta wykorzystuje połowę zdefiniowanego bufora pamięci do znajdowania różnic. Więcej informacji jest dostępnych na stronie wiki TuningMemoryBudget . Zwiększenie rozmiaru bufora może nieco pomóc.

bsdiff to kolejna opcja, ale jest bardzo wymagająca pamięci RAM i całkowicie nieodpowiednia dla jakiegokolwiek rozmiaru obrazu dysku.

bsdiff jest bardzo głodny pamięci. Wymaga max(17*n,9*n+m)+O(1)bajtów pamięci, gdzie njest to rozmiar starego pliku i mjest to rozmiar nowego pliku. bspatch wymaga n+m+O(1)bajtów.

afrazier
źródło
3

Odpowiedź kanoniczna

Jeśli chodzi o rdiff post, librsync 2.0.1 to dobra lektura dla wyjaśnienia funkcji komend, więc wspomniałem o tym poniżej, aby zachować treść tej odpowiedzi, jeśli nic więcej.

Ważne jest, aby postarać się dobrze zrozumieć trzy etapy aktualizacji pliku rdiff : podpis , delta i łatka, o czym mówiono na stronie podręcznika rdiff . Znalazłem również rdiffprzykładowy skrypt polecenia na GitHub, który jest pomocny, do którego odwołam się i zacytuję.

Głównie...

  1. Za pomocą pliku „startowego” lub podstawowego [ file1] tworzysz z niego plik podpisu
    • Jest to zwykle znacznie mniejszy niż sam plik podstawowy / oryginalny
  2. Za pomocą pliku podpisu porównujesz go z innym plikiem [ file2] podobnym do pliku podstawowego, ale innym ( np. Niedawno zaktualizowanym ) i tworzysz plik delta zawierający tylko różnice między dwoma plikami
  3. Użyj pliku „tylko różnice” lub pliku delta i porównaj go z plikiem podstawowym [ file1], aby wygenerować nowy plik zawierający zmiany z drugiego pliku [ file2] pasujące do obu.

Szybkie polecenia (na 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

Wprowadzenie

rdiff to program do obliczania i stosowania delt sieciowych. Delta rdiff to delta między plikami binarnymi, opisująca sposób automatycznej edycji pliku podstawowego (lub starego) w celu utworzenia pliku wynikowego (lub nowego).

W przeciwieństwie do większości programów diff, librsync nie wymaga dostępu do obu plików podczas obliczania diff. Obliczenie delty wymaga tylko krótkiej „sygnatury” starego pliku i pełnej zawartości nowego pliku. Podpis zawiera sumy kontrolne dla bloków starego pliku. Korzystając z tych sum kontrolnych, rdiff znajduje pasujące bloki w nowym pliku, a następnie oblicza różnicę.

delty rdiff są zwykle mniej zwarte i wolniejsze w produkcji niż xdeltas lub zwykłe różnice tekstowe. Jeśli możliwe jest obecność zarówno starych, jak i nowych plików podczas obliczania delty, xdelta generuje ogólnie znacznie mniejszy plik. Jeśli porównywane pliki to zwykły tekst, to GNU diff jest zwykle lepszym wyborem, ponieważ różnice mogą być przeglądane przez ludzi i stosowane jako niedokładne dopasowania.

rdiff sprawdza się, gdy oba pliki nie są wygodne w tym samym czasie. Jednym z przykładów jest to, że dwa pliki znajdują się na osobnych komputerach i chcesz przenieść tylko różnice. Innym przykładem jest przeniesienie jednego z plików do nośnika archiwum lub kopii zapasowej, pozostawiając tylko jego podpis.

Symbolicznie

signature(basis-file) -> sig-file

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

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

Użyj wzorów

Typowym zastosowaniem algorytmu rsync jest przesłanie pliku A2 z komputera A na komputer B, który ma podobny plik A1. Można to zrobić w następujący sposób:

  1. B generuje sygnaturę rdiff dla A1. Nazwij to S1. B wysyła podpis do A. (Podpis jest zwykle znacznie mniejszy niż plik, który opisuje).
  2. A oblicza deltę rdiff między S1 i A2. Nazwij tę deltę D. A wysyła deltę do B.
  3. B stosuje deltę do odtworzenia A2. W przypadkach, w których A1 i A2 zawierają ciągi identycznych bajtów, rdiff powinien zapewnić znaczną oszczędność miejsca.

źródło

Pimp Juice IT
źródło
1
Dziękuję Ci bardzo!
Basj
1

JDIFF to program, który wyświetla różnice między dwoma plikami (binarnymi).

Totti
źródło