Seite 2 von 2
Verfasst: 13.09.2006 12:21
von Proton
@stbi:
Lesen
und verstehen. Ich schrieb: "Wenn es da eine
vernünftige Möglichkeit gebe...."
>>>Zu bedenken ist, dass Patchen von Binärdateien nur bei geringen
>>>Änderungen
sinnvoll ist, da die komplettee Patchinformation relativ
>>>umfangreich im Verhältnis zur eigentlichen Änderung ist
Was meinst du anderes als ich ??

Verfasst: 13.09.2006 13:28
von Kaeru Gaman
Verfasst: 13.09.2006 13:44
von stbi
Proton hat geschrieben:Was meinst du anderes als ich ??

1. gebe ich kein pauschales Statement ab
2. nenne ich Quellen für Algos und Software, anstatt viel Erfolg bei der Suche zu wünschen
3. begründe ich mögliche Einschränkungen
Auch wenn Du letztlich nichts anderes meintest als ich, fängt er mit Deinem Statement wohl herzlich wenig an.
Verfasst: 13.09.2006 14:18
von Proton
Bla

Verfasst: 14.09.2006 12:30
von real
Bei zwei Dateien ist es ja nicht einfach so, dass Datei1 (alt) einfach an bestimmten Stellen verändert werden muss, um zu Datei2 (neu) zu werden. Was machst Du z.B., wenn Datei1 kleiner/größer als Datei2 ist?
Grds. mein Vorschlag:
Reservieren eines Differenzspeichers im RAM. Grds. Vergleich jedes einzelnen Bytes, unveränderte Bytes werden dabei in der Differenz mit $00 gekennzeichnet. Anschließend Differenz packen und als Datei speichern. $00en dürften recht gut zu packen sein, die Differenzdatei sollte dadurch nicht groß werden, wenn sich die Änderungen in Grenzen halten.
Dabei wird nicht beachtet, was ich oben zur Dateigröße geschrieben hab.
Verfasst: 22.09.2006 18:28
von cyan
Hallo... dies ist mein erster Post ^^
ich hab mal die Idee von Real aufgegriffen, und daraus 2 Procedures gemacht... funzt auch, wenn die 2 dateien nicht gleich groß sind...
achja, purebasic ist toll ^^
Code: Alles auswählen
;createpatch(file1.s,file2.s,patchpath.s)
;file1 = Pfad zur alten Version einer Datei
;file2 = Pfad zur neuen Version einer Datei
;Patchpath = Speicherpfad des Patches
Procedure createpatch(file1.s,file2.s,patchpath.s)
Protected MemPoint.l = 0 , LenOfFile1.l , LenOfFile2.l
Protected ByteOld.b , ByteNew.b
Protected *Data1, *Data2, *Data3
;Wenn file1 = file2, Prozedure verlassen
If MD5FileFingerprint(file1) = MD5FileFingerprint(file2)
ProcedureReturn #False
EndIf
ReadFile(0,file1)
ReadFile(1,file2)
LenOfFile1 = Lof(0)
LenOfFile2 = Lof(1)
*Data1 = AllocateMemory(LenOfFile1)
*Data2 = AllocateMemory(LenOfFile2)
*Data3 = AllocateMemory(LenOfFile2+33) ; '+33' für den MD5 Header
ReadData(0,*Data1,LenOfFile1)
ReadData(1,*Data2,LenOfFile2)
PokeS(*Data3,MD5FileFingerprint(file1)) ; Speichert MD5Fingerprint
While MemPoint < LenOfFile2
If MemPoint < LenOfFile1
ByteOld = PeekB(*Data1+MemPoint)
Else
ByteOld = 0
EndIf
ByteNew = PeekB(*Data2+MemPoint)
If ByteOld = ByteNew
PokeB(*Data3+33+MemPoint,0) ;ja nicht den MD5 Header überschreiben
Else
PokeB(*Data3+33+MemPoint,ByteOld-ByteNew)
EndIf
MemPoint = MemPoint + 1
Wend
CreatePack(patchpath)
AddPackMemory(*Data3,LenOfFile2+33,9)
ClosePack()
CloseFile(0) ;keine Ahnung wann man am besten file1 u. file2 closed
CloseFile(1)
FreeMemory(*Data1)
FreeMemory(*Data2)
FreeMemory(*Data3)
ProcedureReturn #True
EndProcedure
Code: Alles auswählen
;patchit(file1.s,pak.s)
;file1 = Pfad zur alten Version einer Datei
;pak = Pfad zum Patch
Procedure patchit(file1.s,pak.s)
Protected ByteOld.b , ByteDiff.b
Protected PakMD5.s
Protected PakSize.l, i.l
Protected *Patch, *DataFile
OpenPack(pak)
*Patch = NextPackFile()
PakSize = PackFileSize()
PakMD5 = PeekS(*Patch,32)
If MD5FileFingerprint(file1) <> PakMD5 ;MD5 überprüfen
ProcedureReturn #False
EndIf
CopyFile(file1,file1+".backup") ;Backup erstellen
OpenFile(0,file1)
For i = 33 To PakSize ;Nachdem MD5Header weiterlesen
FileSeek(0,i-33)
ByteOld = ReadByte(0)
ByteDiff = PeekB(*Patch+i)
FileSeek(0,i-33)
WriteByte(0,ByteOld-ByteDiff)
Next i
If (PakSize-33) < Lof(0) ;Wenn Original-Datei > Update Datei, dann....
FileSeek(0,0)
*DataFile = AllocateMemory(PakSize-33)
ReadData(0,*DataFile,PakSize-33)
CloseFile(0)
DeleteFile(file1)
CreateFile(0,file1)
WriteData(0,*DataFile,PakSize-33)
EndIf
CloseFile(0)
ClosePack()
FreeMemory(*Patch)
FreeMemory(*DataFile)
ProcedureReturn #True
EndProcedure
Verfasst: 22.09.2006 23:49
von pvmichael
@cyan:
Wow, ich bin begeistert, DANKE!, ein erster Test mit einem Textfile hat wunderbar geklappt, werd es mal mit meinen großen EXEn versuchen

Verfasst: 23.09.2006 01:23
von cyan
sollte normal gut funktionieren...
ich hab die patchit-prozedur bisschen optimiert, so, dass sie ihre daten im RAM bearbeitet... so ists eindeutig schneller ^^.... falls interesse, bitte melden
Verfasst: 23.09.2006 12:07
von pvmichael
cyan hat geschrieben:sollte normal gut funktionieren...
ich hab die patchit-prozedur bisschen optimiert, so, dass sie ihre daten im RAM bearbeitet... so ists eindeutig schneller ^^.... falls interesse, bitte melden
Ja, natürlich! Die Dateien mit denen ich es zu tun habe, sind immerhin 200MB groß, da kommst schon auf Geschwindigkeit an

Verfasst: 23.09.2006 12:42
von cyan
bitte schön ^^
Code: Alles auswählen
;patchit(file1.s,pak.s)
;file1 = Pfad zur alten Version einer Datei
;pak = Pfad zum Patch
Procedure patchit(file1.s,pak.s)
Protected ByteOld.b , ByteDiff.b
Protected PakMD5.s
Protected PakSize.l, i.l, lenoffile
Protected *Patch, *DataFile, *Data2
OpenPack(pak)
*Patch = NextPackFile()
PakSize = PackFileSize()
PakMD5 = PeekS(*Patch,32)
If MD5FileFingerprint(file1) <> PakMD5
ProcedureReturn #False
EndIf
CopyFile(file1,file1+".backup")
ReadFile(0,file1)
lenoffile = Lof(0)
*DataFile = AllocateMemory(Lof(0))
*Data2 = AllocateMemory(PakSize-33)
ReadData(0,*DataFile,Lof(0))
CloseFile(0)
For i = 33 To PakSize
If i-33<lenoffile
ByteOld = PeekB(*DataFile+i-33)
Else
ByteOld = 0
EndIf
ByteDiff = PeekB(*Patch+i)
PokeB(*Data2+i-33,ByteOld-ByteDiff)
Next i
DeleteFile(file1)
CreateFile(0,file1)
WriteData(0,*Data2,PakSize-33)
CloseFile(0)
ClosePack()
FreeMemory(*Patch)
FreeMemory(*DataFile)
FreeMemory(*Data2)
ProcedureReturn #True
EndProcedure