Binary diff / patch untuk file besar di linux?


13

Saya punya dua gambar partisi (A dan B) dan ingin menggunakannya untuk membuat tambalan yang dapat saya terapkan pada A di komputer lain untuk mendapatkan gambar B baru tanpa membanjiri jaringan. Saya memiliki persyaratan berikut:

  • bekerja di Linux
  • dapat membuat diff
  • dapat menggunakan diff untuk menambal file
  • dapat menangani file biner
  • dapat menangani file besar (beberapa ratus GB seharusnya berfungsi)
  • tidak diperlukan interaksi pengguna (hanya aplikasi konsol)
  • idealnya, harus dapat membaca dari / menulis ke pipa (sehingga saya dapat pipa ke dalamnya dari file yang dikompresi gzip dan menulis ke satu)

Apakah ada yang seperti itu?


Saya menekan tombol Enter terlalu cepat ketika memulai karunia. Berikut adalah teks yang ingin saya tambahkan:
Basj

Jawaban dengan contoh yang mudah direproduksi untuk rdiffakan berharga untuk referensi di masa mendatang. Contoh: Katakanlah file1dan file2dua file serupa masing-masing 1GB. 1) Bagaimana cara menghitung rdiff? 2) Bagaimana cara menyimpan rdiff ini ke dalam patchfile? 3) Bagaimana cara menerapkan patchfile ini file1untuk memulihkan file2?
Basj

Jawaban:


13

Anda mungkin harus melihat alat yang berhubungan dengan rsync: rdiff dan rdiff-backup . The rdiffperintah memungkinkan Anda menghasilkan file patch dan menerapkannya ke beberapa file lain.

The rdiff-backupperintah menggunakan pendekatan ini untuk menangani seluruh direktori, tapi aku menebak Anda bekerja dengan file tunggal gambar disk, sehingga rdiffakan menjadi orang yang digunakan.


1
Apa arti "tanda tangan" dan "delta" untuk rdiff? Halaman manual tidak mengatakan.
Tor Klingberg

1
Untuk menjawab pertanyaan saya sendiri, membuat delta dengan rdiff adalah proses dua langkah. Pertama buat file tanda tangan dari file lama, lalu gunakan tanda tangan dan file baru untuk membuat delta. Mereka dapat dijalankan bersama denganrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg

1
@TorKlingberg Bisakah Anda mengirim jawaban baru dengan contoh? Katakanlah file1dan file2dua file serupa masing-masing 1GB. 1) Bagaimana cara menghitung diff? 2) Bagaimana cara menyimpan diff ini ke file patch? 3) Bagaimana cara menerapkan file tambalan ini file1untuk memulihkan file2?
Basj

7

xdelta dapat melakukan semua yang Anda inginkan. Peringatan yang adil, jika gambar Anda tidak sangat mirip, Anda dapat berakhir dengan tambalan yang sangat besar, karena xdelta menggunakan setengah dari buffer memori yang ditentukan untuk menemukan perbedaan. Informasi lebih lanjut tersedia di halaman wiki TuningMemoryBudget . Meningkatkan ukuran buffer dapat membantu sedikit.

bsdiff adalah pilihan lain, tetapi RAM sangat lapar dan sama sekali tidak pantas untuk ukuran disk image apa pun.

bsdiff sangat haus akan memori. Ini membutuhkan max(17*n,9*n+m)+O(1)byte memori, di mana nukuran file lama dan mukuran file baru. bspatch membutuhkan n+m+O(1)byte.


3

Jawaban Kanonik

Mengenai rdiff pos, librsync 2.0.1 adalah bacaan yang baik untuk klarifikasi fungsi perintah jadi saya telah merujuknya di bawah ini untuk menjaga konten untuk jawaban ini jika tidak ada yang lain.

Sangat penting untuk mencoba mendapatkan pemahaman yang baik tentang tiga langkah rdiff untuk memperbarui file: tanda tangan , delta , dan patch yang dibicarakan di halaman manual rdiff . Saya juga menemukan rdiffscript contoh perintah di GitHub yang membantu yang akan saya referensi dan kutip.

Intinya ...

  1. Dengan "awal" atau file dasar [ file1] dan Anda membuat file tanda tangan darinya
    • Ini biasanya jauh lebih kecil daripada file dasar / asli itu sendiri
  2. Dengan file tanda tangan Anda membandingkannya dengan file lain [ file2] mirip dengan file dasar Anda tetapi berbeda ( misalnya baru-baru ini diperbarui ) dan membuat file delta yang hanya berisi perbedaan antara dua file
  3. Gunakan "hanya perbedaan" atau file delta dan bandingkan dengan file dasar Anda [ file1] untuk menghasilkan file baru yang berisi perubahan dari file lain [ file2] yang cocok dengan keduanya.

Perintah Cepat (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

pengantar

rdiff adalah program untuk menghitung dan menerapkan delta jaringan. Delta rdiff adalah delta di antara file-file biner, yang menjelaskan bagaimana file basis (atau yang lama) dapat diedit secara otomatis untuk menghasilkan file hasil (atau baru).

Tidak seperti kebanyakan program diff, librsync tidak memerlukan akses ke kedua file ketika diff dihitung. Menghitung delta hanya membutuhkan "tanda tangan" pendek dari file lama dan isi lengkap dari file baru. Tanda tangan berisi checksum untuk blok dari file lama. Dengan menggunakan checksum ini, rdiff menemukan blok yang cocok di file baru, dan kemudian menghitung delta.

delta rdiff biasanya kurang kompak dan juga lebih lambat untuk diproduksi daripada xdeltas atau perbedaan teks biasa. Jika dimungkinkan untuk menghadirkan file lama dan baru saat menghitung delta, xdelta umumnya akan menghasilkan file yang jauh lebih kecil. Jika file yang dibandingkan adalah teks biasa, maka GNU diff biasanya merupakan pilihan yang lebih baik, karena diffs dapat dilihat oleh manusia dan diterapkan sebagai pertandingan yang tidak tepat.

rdiff muncul dengan sendirinya ketika tidak nyaman untuk menghadirkan kedua file secara bersamaan. Salah satu contohnya adalah kedua file berada di mesin yang berbeda, dan Anda hanya ingin mentransfer perbedaannya. Contoh lain adalah ketika salah satu file telah dipindahkan ke arsip atau media cadangan, hanya menyisakan tanda tangannya.

Secara simbolis

signature(basis-file) -> sig-file

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

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

Gunakan pola

Aplikasi khas dari algoritma rsync adalah untuk mentransfer file A2 dari mesin A ke mesin B yang memiliki file A1 yang serupa. Hal ini dapat dilakukan sebagai berikut:

  1. B menghasilkan tanda tangan rdiff dari A1. Sebut S1 ini. B mengirimkan tanda tangan ke A. (Tanda tangan biasanya jauh lebih kecil dari file yang dijelaskannya.)
  2. A menghitung delta rdiff antara S1 dan A2. Sebut delta ini D. A mengirimkan delta ke B.
  3. B menerapkan delta untuk membuat ulang A2. Dalam kasus di mana A1 dan A2 berisi run byte identik, rdiff harus memberikan penghematan ruang yang signifikan.

sumber


1
Terima kasih banyak!
Basj

1

JDIFF adalah program yang menampilkan perbedaan antara dua file (biner).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.