Diff / patch binaire pour les gros fichiers sur Linux?


13

J'ai deux images de partition (A et B) et je veux les utiliser pour créer un patch que je peux appliquer sur A sur un autre ordinateur afin d'obtenir la nouvelle image B sans inonder le réseau. J'ai les exigences suivantes:

  • fonctionne sous Linux
  • peut créer des diffs
  • peut utiliser des différences pour patcher des fichiers
  • peut gérer des fichiers binaires
  • peut gérer des fichiers volumineux (quelques centaines de Go devraient fonctionner)
  • aucune interaction utilisateur requise (juste une application console)
  • idéalement, devrait être capable de lire / écrire dans des tuyaux (pour que je puisse y accéder à partir d'un fichier compressé avec gzip et y écrire)

Existe-t-il quelque chose comme ça?


J'ai appuyé trop rapidement sur la touche Entrée lors du démarrage de la prime. Voici le texte que je voulais ajouter:
Basj

Une réponse avec un exemple facile à reproduire rdiffserait utile pour référence future. Exemple: Disons file1et file2sont deux fichiers similaires de 1 Go chacun. 1) Comment calculer le rdiff? 2) Comment enregistrer ce rdiff dans un patchfichier? 3) Comment appliquer ce patchfichier file1pour récupérer file2?
Basj

Réponses:


13

Vous devriez probablement jeter un œil aux outils liés à rsync: rdiff et rdiff-backup . La rdiffcommande vous permet de produire un fichier patch et de l'appliquer à un autre fichier.

La rdiff-backupcommande utilise cette approche pour traiter des répertoires entiers, mais je suppose que vous travaillez avec des images de disque à fichier unique, ce rdiffsera donc celle à utiliser.


1
Que signifient "signature" et "delta" pour rdiff? La page de manuel ne dit pas.
Tor Klingberg

1
Pour répondre à ma propre question, la création d'un delta avec rdiff est un processus en deux étapes. Créez d'abord un fichier de signature à partir de l'ancien fichier, puis utilisez la signature et le nouveau fichier pour créer le delta. Ils peuvent être exécutés avecrdiff signature oldfile | rdiff delta - newfile deltafile
Tor Klingberg

1
@TorKlingberg Pourriez-vous publier une nouvelle réponse avec un exemple? Disons file1et file2sont deux fichiers similaires de 1 Go chacun. 1) Comment calculer le diff? 2) Comment enregistrer ce diff dans un fichier patch? 3) Comment appliquer ce fichier patch file1pour récupérer file2?
Basj

7

xdelta peut faire tout ce que vous voulez. Bon avertissement cependant, si vos images ne sont pas très similaires, vous pouvez vous retrouver avec un très gros patch, car xdelta utilise la moitié de la mémoire tampon définie pour trouver les différences. Plus d'informations sont disponibles sur la page wiki TuningMemoryBudget . L'augmentation de la taille du tampon peut aider un peu.

bsdiff est une autre option, mais il est très gourmand en RAM et totalement inapproprié pour tout ce qui a la taille d'une image disque.

bsdiff est assez gourmand en mémoire. Il nécessite des max(17*n,9*n+m)+O(1)octets de mémoire, où nest la taille de l'ancien fichier et mla taille du nouveau fichier. bspatch nécessite des n+m+O(1)octets.


3

Réponse canonique

En ce qui concerne rdiff le message, librsync 2.0.1 est une bonne lecture pour la clarification des fonctionnalités de la commande, j'ai donc référencé cela ci-dessous pour conserver le contenu de cette réponse si rien d'autre.

Il est important d'essayer de bien comprendre les trois étapes de rdiff pour mettre à jour un fichier: signature , delta et patch, comme indiqué sur la page de manuel rdiff . J'ai également trouvé un rdiffexemple de script de commande sur GitHub qui est utile que je vais référencer et citer.

Essentiellement...

  1. Avec un fichier de départ ou de base [ file1] et vous créez un fichier de signature à partir de celui-ci
    • C'est généralement beaucoup plus petit que le fichier de base / original lui-même
  2. Avec le fichier de signature, vous le comparez à un autre fichier [ file2] similaire à votre fichier de base mais différent ( par exemple récemment mis à jour ) et créez un fichier delta contenant uniquement les différences entre les deux fichiers
  3. Utilisez le fichier "différences uniquement" ou delta et comparez-le avec votre fichier de base [ file1] pour générer un nouveau fichier contenant les modifications de l'autre fichier [ file2] correspondant aux deux.

Commandes rapides (par 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

introduction

rdiff est un programme pour calculer et appliquer des deltas de réseau. Un delta rdiff est un delta entre des fichiers binaires, décrivant comment un fichier de base (ou ancien) peut être automatiquement modifié pour produire un fichier de résultat (ou nouveau).

Contrairement à la plupart des programmes diff, librsync n'a pas besoin d'accéder aux deux fichiers lorsque le diff est calculé. Le calcul d'un delta ne nécessite qu'une courte "signature" de l'ancien fichier et le contenu complet du nouveau fichier. La signature contient des sommes de contrôle pour les blocs de l'ancien fichier. À l'aide de ces sommes de contrôle, rdiff trouve les blocs correspondants dans le nouveau fichier, puis calcule le delta.

Les deltas rdiff sont généralement moins compacts et aussi plus lents à produire que les xdeltas ou les différences de texte standard. S'il est possible d'avoir à la fois l'ancien et le nouveau fichier présents lors du calcul du delta, xdelta produira généralement un fichier beaucoup plus petit. Si les fichiers comparés sont en texte brut, alors GNU diff est généralement un meilleur choix, car les différences peuvent être vues par les humains et appliquées comme des correspondances inexactes.

rdiff prend tout son sens lorsqu'il n'est pas pratique d'avoir les deux fichiers présents en même temps. Un exemple de cela est que les deux fichiers se trouvent sur des machines distinctes et que vous souhaitez transférer uniquement les différences. Un autre exemple est lorsque l'un des fichiers a été déplacé vers un support d'archivage ou de sauvegarde, ne laissant que sa signature.

Symboliquement

signature(basis-file) -> sig-file

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

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

Utiliser des modèles

Une application typique de l'algorithme rsync consiste à transférer un fichier A2 d'une machine A vers une machine B qui a un fichier similaire A1. Cela peut être fait comme suit:

  1. B génère la signature rdiff de A1. Appelez cela S1. B envoie la signature à A. (La signature est généralement beaucoup plus petite que le fichier qu'elle décrit.)
  2. A calcule le delta rdiff entre S1 et A2. Appelez ce delta D. A envoie le delta à B.
  3. B applique le delta pour recréer A2. Dans les cas où A1 et A2 contiennent des séquences d'octets identiques, rdiff devrait permettre un gain d'espace important.

la source


1
Merci beaucoup!
Basj

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.