Lad os sige, at jeg har en 4 GB-fil abc på min lokal computer. Jeg har uploadet den til en fjern server via SFTP, det tog et par timer. 
 Nu har jeg lidt ændret filen (sandsynligvis maksimalt 50 MB, men ikke på hinanden følgende byte i denne fil) lokalt, og gemte det i abc2. Jeg gemte også den originale fil abc på min lokale computer. 
  Sådan beregnes en binær diff på abc og abc2?  
Applikationer:
- 
Jeg kunne kun sende en patch-fil (sandsynligvis maks. 100 MB) til den fjerne server i stedet for at geninstallere heleabc2filen (det ville tage et par timer igen!), og genskababc2på den fjerne server kun fraabcogpatch.
- 
Lokalt, i stedet for at spilde 8 GB til backup af både abcogabc2, kunne jeg kun gemmeabc+patch, så det tager kun < 4100 MB.
Hvordan gør man det?
 PS: for tekst kender jeg diff, men her leder jeg efter noget, der kunne fungere for ethvert rå binært format, det kunne være zip-filer eller eksekverbare filer eller endda andre filtyper. 
 PS2: Hvis det er muligt, vil jeg ikke bruge rsync; Jeg ved, at det kan replikere ændringer mellem 2 computere på en effektiv måde (ikke videresende data, der ikke er ændret), men her vil jeg virkelig have en patch -fil, der kan reproduceres senere, hvis Jeg har både abc og patch. 
Svar
 Til det andet program / problem vil jeg bruge et deduplicering af sikkerhedskopieringsprogram som restic eller borgbackup i stedet for at prøve for manuelt at holde styr på “patches” eller diffs. restic sikkerhedskopieringsprogrammet giver dig mulighed for at sikkerhedskopiere mapper fra flere maskiner til det samme sikkerhedskopier og deduplicere sikkerhedskopidataene blandt fragmenter af filer fra en enkelt maskine såvel som mellem maskinen. (Jeg har ingen brugeroplevelse med borgbackup, så jeg kan ikke sige noget om dette program.) 
 Beregning og lagring af en diff af abc og abc2 filer kan gøres med rsync. 
 Dette er et eksempel med abc og abc2 153 MB. Filen abc2 er blevet ændret ved at overskrive første 2,3 MB af filen med nogle andre data: 
 $ ls -lh total 626208 -rw-r--r-- 1 kk wheel 153M Feb 3 16:55 abc -rw-r--r-- 1 kk wheel 153M Feb 3 17:02 abc2  
 Vi opretter ud patch til at omdanne abc til abc2 og kalde det abc-diff: 
 $ rsync --only-write-batch=abc-diff abc2 abc  
 $ ls -lh total 631026 -rw-r--r-- 1 kk wheel 153M Feb 3 16:55 abc -rw------- 1 kk wheel 2.3M Feb 3 17:03 abc-diff -rwx------ 1 kk wheel 38B Feb 3 17:03 abc-diff.sh -rw-r--r-- 1 kk wheel 153M Feb 3 17:02 abc2  
 Den genererede fil abc-diff er den faktiske diff (din “patch-fil”), mens abc-diff.sh eret kort shell-script, som rsync opretter til dig: 
 $ cat abc-diff.sh rsync --read-batch=abc-diff ${1:-abc}  
 Dette script ændrer abc, så det bliver identisk med abc2, givet filen abc-diff: 
 $ md5sum abc abc2 be00efe0a7a7d3b793e70e466cbc53c6 abc 3decbde2d3a87f3d954ccee9d60f249b abc2 $ sh abc-diff.sh $ md5sum abc abc2 3decbde2d3a87f3d954ccee9d60f249b abc 3decbde2d3a87f3d954ccee9d60f249b abc2  
 Filen abc-diff kunne nu overføres til hvor som helst du har abc. Med kommandoen rsync --read-batch=abc-diff abc anvender du patch til filen abc og omdanner dens indhold til at være det samme som abc2 -fil på det system, hvor du oprettede diff. 
Genanvendelse af programrettelsen en anden gang virker sikkert. Der er ingen fejlmeddelelser, og heller ikke ændres filens indhold (MD5-kontrolsummen ændres ikke.).
Bemærk, at medmindre du opretter en eksplicit “omvendt patch”, er der ingen måde at fortryde applikationen let af plasteret.
 Jeg testede også at skrive 2,3 MB-modifikationen til et andet sted i abc2 -dataene lidt længere inde (ca. 50 MB) såvel som i starten. Den genererede “patch” var 4,6 MB stor, hvilket antyder, at kun de modificerede bits blev gemt i patchen. 
Kommentarer
-  Mange tak @Kusalananda, det ‘ er fantastisk! PS: rsync --read-batch=abc-diff ${1:-abc}(automatisk genereret .sh-script) gavremote destination is not allowed with --read-batchrsync error: syntax or usage error (code 1) at main.c(1326) [Receiver=3.1.2], menrsync --read-batch=abc-diff abcfungerede med succes.Hvad er forskellen mellem disse to lignende kommandoer?
-  2/2 Er der en måde at tage abcsom input, anvende patchdiff-abcmed--read-batchmen ændrer ikkeabc” på stedet “, men snarere output til en ny filabc3? (hvis muligt alle medrsyncuden rør, så det fungerer let på Linux såvel som Windows, som også harrsync.exetilgængelig)
-  @Basj Kommandoerne ville gøre forskellige ting, hvis $1havde en værdi.${1:-abc}betyder ” brug den første positionsparameter ($1), medmindre den ‘ er tom eller udefineret. Hvis det ‘ er tomt eller udefineret, skal du brugeabci stedet for “. Jeg ‘ antager, at$1havde en værdi, da du prøvede det, muligvis noget, det fortolkes som en ekstern destinationsadresse.
- @Basj I ‘ Jeg er ikke helt sikker på, at dette er muligt, men jeg ‘ ll kig i morgen efter søvn.
-  Tak for dit svar om ${1:-abc}. Det mislykkedes sandsynligvis, fordi jeg prøvede det på Windows (jeg ‘ m ved hjælp af rsync både på Linux til min fjerne server og Windows lokalt). Men det er ‘ perfekt, darsync --read-batch=abc-diff abcfungerer 🙂
Svar
Hvordan beregnes en binær diff af abc og abc2?
Brug af bsdiff / bspatch eller xdelta og andre.
$ bsdiff older newer patch.bin # patch.bin is created [...] $ bspatch older newer patch.bin # newer is created Disse advarsler fra mandsiderne skal dog bemærkes:
-  bsdiffbruger hukommelse svarende til 17 gange størrelsen på oldfile , og kræver en absolut minimumsstørrelse på arbejdssættet på 8 gange størrelsen på oldfile .
-  bspatchbruger hukommelse svarende til størrelsen på oldfile plus størrelsen på newfile , men tåler et meget lille arbejdssæt uden et dramatisk tab af ydeevne.
Kommentarer
Svar
 Har du prøvet bare at tvinge diff for at behandle filerne som tekst: 
diff -ua abc abc2 Som forklaret her .
-  -uoutput NUM (standard 3) linjer i en samlet kontekst
-  -abehandle alle filer som tekst
Dette skal give dig en patch. Ulempen ved dette er, at “linjerne” kan være ret lange, og det kan svulme plasteret op.
Kommentarer
-  Ups, ja du don ‘ t vil faktisk have n. Jeg ‘ er interesseret i at vide, om det fungerer, da jeg ‘ er ikke sikker på, hvor længe ” linjer ” vil være.
-  Tak for din kommentar! Jeg oprettede to meget ens 256 MB filer abcogabc2. Så prøvede jegdiff -ua abc abc2 > patch, så kopierede jegabctilabc3og jeg forsøgte at komme migabc2takket væreabc3ogpatch:patch abc3 < patch, men det fungerede ikke: i slutningen varabc3kun 1 KB i stedet for 256 MB. Har du nogen idé?
- Hmmm, ved ikke hvad der skete. Jeg gjorde det bare på min maskine, og det fungerede bedre, end jeg havde forventet.Jeg tog en 382M-fil, der var tilfældige heltal skrevet ud i binær til en fil. Jeg ændrede 3 byte i det og gjorde diff og patch, og det fungerede. De resulterende filer var md5sum lige.
-  Hvis en stor fil ikke har nogen byte 0x0a, dvs. newline eller meget få, formoder jeg, at den ikke ville ‘ fungerer ikke så godt, det ville være interessant at teste.
-  Åh helt sikkert. Du kan lave et veluddannet gæt på en binær med wc -lsom vil kigge efter linjeskift og efter min erfaring kører meget hurtigt. Jeg forventer på en vilkårlig binær, at det fungerer ret godt. For eksempel på min maskine fandt jeg en 252M mp4, der havde 1,2 millioner ” linjer “, og en 59M.deb, der havde ca. 230k, så gennemsnit ” linjer ” på henholdsvis mindre end 220 bytes og 258 bytes. Jeg kan ikke ‘ ikke se, hvorfor disse filer ville være så forskellige end andre, men du kunne helt sikkert blive uheldig. I praksis formoder jeg, at det ville fungere ret godt, og hvis ikke, er det ‘ stadig et sjovt hack.
Svar
Brug xdelta , det blev oprettet nøjagtigt til denne type anvendelser. Baseret på VCDIFF (RFC 3284) i de nyeste versioner.
Kommentarer
-  Linket fungerer ikke (er der en anden URL?). Kan du også tilføje et eksempel på nogle få linjer for at vise, hvordan du: 1) beregner diff patch-filen, og 2) gendannerabc2, kun givetabcogpatch?
- Beklager, fast URL
- Tak @vonbrand . Vil du have et sådant eksempel?
Svar
Supplerer til andre svar i henhold til mine tests:
 Med diff 
 oprettede jeg to meget ens 256 MB filer abc og abc2. Lad os derefter oprette diff-filen: 
diff -ua abc abc2 > abc-abc2.diff  Lad os nu prøve at gendanne abc2 takket være original abc fil og abc-abc2.diff: 
cp abc abc3 patch abc3 < abc-abc2.diff eller
cp abc abc3 patch abc3 -i abc-abc2.diff eller
patch abc -i abc-abc2.diff -o abc3  Det fungerer på Linux. Jeg prøvede også på Windows (patch.exe og diff.exe er også tilgængelige), men af en ukendt årsag mislykkedes det: den producerede abc3 -fil er kun 1 KB i stedet for 256 MB (I ” Opdater dette svar senere her). 
 Med rsync 
Som beskrevet i det accepterede svar fungerer dette:
rsync --only-write-batch=abc-abc2-diff abc2 abc cp abc abc3 rsync --read-batch=abc-abc2-diff abc3  Med rdiff 
Som beskrevet i dette svar , dette er også en løsning:
rdiff signature abc abc-signature rdiff delta abc-signature abc2 abc-abc2-delta rdiff patch abc abc-abc2-delta abc3 Testet også på Windows med rdiff.exe fra her og det fungerer.
Kommentarer
-  Jeg ‘ jeg gætter på patch mislykkedes på Windows, fordi den læste inputfilen i ” tekst ” -tilstand, der signalerer slutningen af filen, når den støder på en KONTROL -Z (byte 0x18) i inputfilen. Dette er en ældre tilstand fra tidlige DOS-dage, hvor biblioteket ikke registrerede længden på filen, og så blev fillængden beregnet ud fra antallet af 512 byte sektorer. Hvis du kan fortælle patchat åbne filen i binær tilstand, skal den ikke ‘ ikke have denne fejl.
bsdiff uses memory equal to 17 times the size of oldfileså dette vinder ‘ fungerer normalt ikke til 4 GB filer (i det mindste på min 8 GB RAM-maskine).mydiff abc abc2 > patchfileogmypatch abc patchfile > abc3) uanset størrelse. Også, hvis jeg hugger i 128 MB stykker, hvad sker der hvis den første 1 GBabc== den sidste (efterfølgende) 1 GBabc2? Når vi ‘ sammenlignerabc-first128mbmedabc2-first128mb, findes der ingen match, så det måske ikke effektiv?