Бінарний diff / patch для великих файлів на Linux?


13

У мене є два зображення розділу (A і B) і хочу використовувати їх для створення патча, який я можу застосувати на A на іншому комп'ютері, щоб отримати нове зображення B, не затоплюючи мережу. У мене є такі вимоги:

  • працює в Linux
  • може створити різницю
  • може використовувати diff для патч-файлів
  • може обробляти двійкові файли
  • може обробляти великі файли (кілька сотень ГБ повинні працювати)
  • не потрібно взаємодії з користувачем (лише консольна програма)
  • в ідеалі, слід вміти читати з / записувати на труби (щоб я міг передати в нього файл, стиснутий файлом gzip, і записати в один)

Чи існує щось подібне?


Я натискаю клавішу Enter занадто швидко, коли запускаю щедроту. Ось текст, який я хотів додати:
Basj

Відповідь на прикладі, який легко відтворити, rdiffбув би цінним для подальшого використання. Приклад: Скажімо, file1і file2це два подібних файли по 1 ГБ кожен. 1) Як обчислити rdiff? 2) Як зберегти цей rdiff у patchфайл? 3) Як застосувати цей patchфайл file1до відновлення file2?
Бась

Відповіді:


13

Напевно, варто поглянути на інструменти, пов'язані з rsync: rdiff та rdiff-backup . rdiffКоманда дозволяє створити файл патч і застосувати його до якого - або іншого файлу.

rdiff-backupКоманда використовує цей підхід для вирішення цілих каталогів, але я припускаю , що ви працюєте з образами дисків одного файлу, так rdiffбуде один для використання.


1
Що означає "підпис" та "дельта" для rdiff? Сторінка man не говорить.
Tor Klingberg

1
Щоб відповісти на моє власне запитання, створення дельти з rdiff - це процес у два етапи. Спочатку створіть файл підпису зі старого файлу, потім використовуйте підпис та новий файл для створення дельти. Їх можна запустити разом зrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg

1
@TorKlingberg Чи можете ви опублікувати нову відповідь із прикладом? Скажімо, file1і file2це два подібних файли по 1 ГБ кожен. 1) Як обчислити різницю? 2) Як зберегти це відмінність у патч-файлі? 3) Як застосувати цей патч-файл file1для відновлення file2?
Бась

7

xdelta може робити все, що завгодно. Хоча справедливе попередження, якщо ваші зображення не дуже схожі, ви можете отримати дуже великий патч, оскільки xdelta використовує половину визначеного буфера пам'яті для знаходження відмінностей. Додаткову інформацію можна отримати на сторінці вікі TuningMemoryBudget . Збільшення розміру буфера може трохи допомогти.

bsdiff - це ще один варіант, але він дуже голодний і швидко не відповідає розміру зображення на диску.

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 . Я також знайшов rdiffна GitHub скрипт прикладу команди, який корисний, на який я посилаюсь і цитую.

По суті ...

  1. За допомогою "стартового" або базового файлу [ file1] і ви створюєте з нього файл підпису
    • Зазвичай це набагато менше, ніж сам базовий / оригінальний файл
  2. За допомогою файлу підпису ви порівнюєте його з іншим файлом [ file2], подібним до базового файлу, але різним ( наприклад, нещодавно оновленим ) та створюєте файл дельти, що містить лише відмінності між двома файлами
  3. Використовуйте файл "лише відмінності" або дельта і порівняйте його з базовим файлом [ file1], щоб створити новий файл, що містить зміни з іншого файлу [ file2], що відповідає двом.

Швидкі команди (за 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 - це дельта між бінарними файлами, що описує, як базовий (або старий) файл може бути автоматично відредагований для отримання результату (або нового) файлу.

На відміну від більшості програм, що відрізняються, librsync не вимагає доступу до обох файлів при обчисленні diff. Для обчислення дельти потрібно лише короткий "підпис" старого файлу та повний вміст нового файлу. Підпис містить контрольні суми для блоків старого файлу. Використовуючи ці контрольні суми, rdiff знаходить відповідні блоки у новому файлі, а потім обчислює дельту.

Дельти rdiff зазвичай менш компактні, а також більш повільні, ніж xdeltas або звичайний текст. Якщо під час обчислення дельти можливо мати присутні як старі, так і нові файли, xdelta, як правило, створює набагато менший файл. Якщо файли, що порівнюються, є текстовими текстами, то GNU diff - це, як правило, кращий вибір, оскільки різні можуть переглядатись людьми та застосовуватись як неточні збіги.

rdiff стає своїм, коли не зручно одночасно бути присутніми обидва файли. Одним із прикладів цього є те, що два файли знаходяться на окремих машинах, і ви хочете передати лише відмінності. Інший приклад - коли один з файлів переміщено до архіву чи резервного копіювання носія, залишивши лише його підпис.

Символічно

signature(basis-file) -> sig-file

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

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

Використовуйте візерунки

Типовим застосуванням алгоритму rsync є передача файлу A2 з машини A на машину B, яка має аналогічний файл A1. Це можна зробити так:

  1. B породжує rdiff підпис A1. Зателефонуйте цьому S1. B надсилає підпис А. (Підпис зазвичай набагато менший, ніж файл, який він описує.)
  2. Обчислює дельту rdiff між S1 та A2. Назвіть цю дельту D. А відправляє дельту до В.
  3. B застосовує дельту для відтворення A2. У випадках, коли A1 і A2 містять прогони однакових байтів, rdiff повинен забезпечити значну економію місця.

джерело


1
Дуже дякую!
Бась

1

JDIFF - програма, яка виводить відмінності між двома (бінарними) файлами.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.