Diff / patch binaria per file di grandi dimensioni su Linux?


13

Ho due immagini di partizione (A e B) e voglio usarle per creare una patch che posso applicare su A su un altro computer per ottenere la nuova immagine B senza inondare la rete. Ho i seguenti requisiti:

  • funziona su Linux
  • può creare differenze
  • può usare diff per patch file
  • può gestire file binari
  • può gestire file di grandi dimensioni (alcune centinaia di GB dovrebbero funzionare)
  • nessuna interazione dell'utente richiesta (solo un'applicazione console)
  • idealmente, dovrebbe essere in grado di leggere / scrivere su pipe (in modo da poterlo inserire da un file compresso con gzip e scriverne uno)

Esiste qualcosa del genere?


Ho premuto il tasto Invio troppo velocemente quando ho iniziato la taglia. Ecco il testo che volevo aggiungere:
Basj,

Una risposta con un esempio facile da riprodurre rdiffsarebbe utile per riferimento futuro. Esempio: diciamo file1e file2sono due file simili da 1 GB ciascuno. 1) Come calcolare il rdiff? 2) Come salvare questo rdiff in un patchfile? 3) Come applicare questo patchfile file1per recuperare file2?
Basj

Risposte:


13

Probabilmente dovresti dare un'occhiata agli strumenti relativi a rsync: rdiff e rdiff-backup . Il rdiffcomando consente di produrre un file patch e applicarlo a qualche altro file.

Il rdiff-backupcomando usa questo approccio per gestire intere directory, ma suppongo che tu stia lavorando con immagini del disco a file singolo, quindi rdiffsarà quella da usare.


1
Cosa significano "firma" e "delta" per rdiff? La pagina man non dice.
Tor Klingberg,

1
Per rispondere alla mia domanda, creare un delta con rdiff è un processo in due fasi. Prima crea un file di firma dal vecchio file, quindi usa la firma e il nuovo file per creare il delta. Possono correre insieme ardiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg il

1
@TorKlingberg Potresti pubblicare una nuova risposta con un esempio? Diciamo che file1e file2sono due file simili di 1 GB ciascuno. 1) Come calcolare il diff? 2) Come salvare questa diff in un file patch? 3) Come applicare questo file patch file1per ripristinare file2?
Basj

7

xdelta può fare tutto ciò che vuoi. Tuttavia, se le tue immagini non sono molto simili, puoi finire con una patch molto grande, perché xdelta usa metà del buffer di memoria definito per trovare le differenze. Maggiori informazioni sono disponibili sulla pagina wiki TuningMemoryBudget . L'aumento della dimensione del buffer può essere di aiuto.

bsdiff è un'altra opzione, ma è molto affamato di RAM e completamente inappropriato per qualsiasi dimensione delle dimensioni di un'immagine del disco.

bsdiff ha molta fame di memoria. Richiede max(17*n,9*n+m)+O(1)byte di memoria, dove nsono le dimensioni del vecchio file e mle dimensioni del nuovo file. bspatch richiede n+m+O(1)byte.


3

Risposta canonica

Per quanto riguarda rdiff il post, librsync 2.0.1 è una buona lettura per il chiarimento della funzionalità del comando, quindi ho fatto riferimento di seguito per preservare il contenuto di questa risposta se non altro.

È importante provare a comprendere bene rdiff in tre passaggi per l'aggiornamento di un file: firma , delta e patch, come indicato nella pagina man di rdiff . Ho anche trovato utile uno rdiffscript di esempio di comando su GitHub che farò riferimento e citerò.

Essenzialmente...

  1. Con un "avvio" o file di base [ file1] e si crea un file di firma da esso
    • Questo di solito è molto più piccolo del file base / originale stesso
  2. Con il file della firma lo confronti con un altro file [ file2] simile al file di base ma diverso ( ad es. Aggiornato di recente ) e si crea un file delta contenente solo le differenze tra i due file
  3. Utilizzare il "solo differenze" o il file delta e confrontarlo con il file di base [ file1] per generare un nuovo file contenente le modifiche dall'altro file [ file2] corrispondenti ai due.

Comandi rapidi (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

introduzione

rdiff è un programma per calcolare e applicare delta di rete. Un delta rdiff è un delta tra i file binari, che descrive come un file base (o vecchio) può essere modificato automaticamente per produrre un file risultato (o nuovo).

A differenza della maggior parte dei programmi diff, librsync non richiede l'accesso ad entrambi i file quando viene calcolato il diff. Il calcolo di un delta richiede solo una breve "firma" del vecchio file e il contenuto completo del nuovo file. La firma contiene checksum per i blocchi del vecchio file. Usando questi checksum, rdiff trova i blocchi corrispondenti nel nuovo file e quindi calcola il delta.

I delta rdiff sono generalmente meno compatti e anche più lenti da produrre rispetto a xdeltas o diff diff di testo. Se è possibile avere sia il vecchio che il nuovo file presenti quando si calcola il delta, xdelta generalmente produrrà un file molto più piccolo. Se i file confrontati sono in chiaro, allora GNU diff è di solito una scelta migliore, poiché i diff possono essere visualizzati dagli umani e applicati come corrispondenze inesatte.

rdiff si presenta da solo quando non è conveniente avere entrambi i file presenti contemporaneamente. Un esempio di ciò è che i due file si trovano su macchine separate e si desidera trasferire solo le differenze. Un altro esempio è quando uno dei file è stato spostato nel supporto di archiviazione o di backup, lasciando solo la sua firma.

simbolicamente

signature(basis-file) -> sig-file

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

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

Usa schemi

Un'applicazione tipica dell'algoritmo rsync è quella di trasferire un file A2 da una macchina A a una macchina B che ha un file simile A1. Questo può essere fatto come segue:

  1. B genera la firma rdiff di A1. Chiama questo S1. B invia la firma ad A. (La firma è di solito molto più piccola del file che descrive.)
  2. A calcola il delta rdiff tra S1 e A2. Chiamare questo delta D. A invia il delta a B.
  3. B applica il delta per ricreare A2. Nei casi in cui A1 e A2 contengano esecuzioni di byte identici, rdiff dovrebbe offrire un notevole risparmio di spazio.

fonte


1
Grazie mille!
Basj

1

JDIFF è un programma che genera le differenze tra due file (binari).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.