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
stbi hat geschrieben:Jeder lahme Autofahrer setzt aus diesem Grund nen Hut auf :D
:lol: :mrgreen: :allright: :twisted:

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 ^^ :mrgreen: :mrgreen:
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 :D

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