Seite 1 von 2

Suche & ersetze eine Hex oder Bin Kombination in einer D

Verfasst: 17.05.2007 16:30
von String
Hallo!
Ich suche eine möglichst schnell arbeitende Lösung für folgendes Problem.
Suche in einer Datei (kann durchaus eine Größe von 500MB und mehr haben)
Eine Kombination von Hex oder Bin Werten z.B. ( FF 30 E8 )
Ersetze diese dann durch z.B. ( 20 45 B3 )
Und wider Speichern.

Ein Code währe schon schön.
Aber ein Ansatz zum Ziel (link : Hab leider nichts gefunden)
würde mir auch reichen.

Verfasst: 17.05.2007 18:02
von Andreas_S
Was möchtest du machen?

Einen ASCCI-Wert in Hexa und Binären Zahlen darstellen?

Verfasst: 17.05.2007 18:03
von Xaby
PBprogger hat geschrieben:Was möchtest du machen?

Einen ASCCI-Wert in Hexa und Binären Zahlen darstellen?
Zwei "I" statt zwei "C" :? :allright:

Verfasst: 17.05.2007 18:06
von Andreas_S
HM :?. Versteh ich nicht. Mit ReplaceString(String$, SuchString$, ErsatzString$ [, Modus [, StartPosition]]) vielleicht.

Verfasst: 17.05.2007 18:17
von String
Habe ich eventuell ein wenig unglücklich formuliert.
Hier Mal ein Code der das ganze verdeutlichen soll.

Hierbei benutze ich einen String der mit kleinen Dateien ja auch zurecht kommt.
Was mach ich aber bei 500 MB Dateien.

Code: Alles auswählen

#File = 0
#File2 = 0
Global Laenge.l
Global RetVal.s


Procedure.s LeseBIN(Filename.s) 
    If ReadFile(#FILE,Filename.s)  
        Laenge.l = Lof(#FILE)
        Repeat 
            MyByte.b = ReadByte(#File)
            If MyByte.b < 0
              MyByteL.l = 256 + MyByte.b
            Else
              MyByteL.l = MyByte.b
            EndIf
      ;      RetVal.s = RetVal.s + RSet(Hex(MyByteL.l), 2, "0") + "-"
            RetVal.s = RetVal.s + Str(MyByteL.l) + "-"               
        Until Eof(#File) 
        CloseFile(#File) 
    Else
      Debug "Datei nicht gefunden "
      End
    EndIf 
    ProcedureReturn RetVal.s 
EndProcedure 



Procedure.s SchreibeBIN(Filename.s) 
    If OpenFile(#FILE2,Filename.s)  
      For k = 1 To CountString(RetVal.s, "-")
        MyByteS.b  = Val(StringField(RetVal.s, k, "-"))
        WriteByte(#File2, MyByteS.b)
      Next
      CloseFile(#File2)  
    EndIf
    ProcedureReturn RetVal.s 
EndProcedure 


Datei1.s = "E:\0001\TestA.zip"
Datei2.s = "E:\0001\TestB.zip"

LeseBIN(Datei1) 

; Debug RetVal.s
RetVal.s = ReplaceString(RetVal.s,  "80-75-3", "77-97-100" )
; Debug RetVal.s

If FileSize(Datei2.s) = -1
  SchreibeBIN(Datei2) 
  Debug "OK"
Else
  Debug "Achtung die Datei 2 existiert schon"
EndIf  




Verfasst: 17.05.2007 18:25
von ts-soft
Mit Strings arbeiten ist schon mal verkehrt, es geht ja um Binärdateien, die
gehen nunmal nicht in Strings!

Byteweise auf der Festplatte ist wohl zu langsam, also die Datei
häppchenweise in den Memory einlesen (ReadData) und dann vergleichen,
danach den nächsten Happen usw.

Byteweise durch den Happen bewegen, wenn er dem ersten Byte entspricht,
die anderen beiden Bytes prüfen und direkt in den Speicher schreiben.

Am besten die Happen immer gleich wieder in eine neue Datei schreiben.

Den Code wirste Dir wohl selber schreiben müssen :mrgreen:

Verfasst: 17.05.2007 18:27
von Xaby
Meine erste Idee war so:


Code: Alles auswählen

Procedure.l ValH(S$)
  Hex$="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
  
EndProcedure


Procedure.s DezTo(Z.l, Basis.b);
 HexStr.s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 HlpStr.s=""; { Wandelt Dezimal zahlen in andere Zahlensysteme um }
 If Zahl=0 THEN HlpStr:='0' Else HlpStr := '';
  While Zahl <> 0 
    HlpStr = Mid(HexStr, (Zahl % Basis)+1,1)+HlpStr;
    Zahl = Zahl / Basis;
  Wend;
  ProcedureReturn HelpStr
EndProcedure;


SuchWord.w=3565
ErsetzWord.w=3560

Name.s="c:\test.txt"
L=FileSize(Name)

If L>0 ; by Null brauchst ja nicht durchsuchen, steht ja nix drin
OpenFile(0,Name)
  SuchDings  
  While A<L
   If SuchWord=ReadWord(0)
     FileSeek(0,A) 
     WriteWord(0,ErsetzWord)
   EndIf
  A+2
  Wend

CloseFile(0)
EndIf
Weil du ja von Hex-Werten zurück das haben wolltest.
Kümmer mich gleich drum, dass du Hexwerte als String eingibst und die dann als Word oder was du brauchst auslesen kannst.
Ansonsten, wenn du dir nicht sicher bist, wo dein Wert auftaucht, kannst du auch jedes Byte einzeln auslesen und immer zwei aufeinander folgende Bytes zusammenrechnen.

Perfomancegewinn wirst du erhalten, wenn du Buffer benutzt und gleich ein bisschen mehr auf einmal ausliest.

Vielleicht kann der Buffer auch 500 MB sein. :?

Zum Thema häppchen.
http://www.purebasic.fr/german/viewtopi ... ht=hjsplit


:allright:

Verfasst: 17.05.2007 18:59
von String
Danke ! an Alle für eure Hilfe.
Jetzt bekomme ich das schon irgendwie hin.
Mit String habe ich ja nur wegen (ReplaceString) gearbeitet.
War wohl ein Fehler.

Xaby Danke für den Code.

Verfasst: 17.05.2007 19:06
von ts-soft
Je nachdem wie groß die Dateien sind, solltest Du Dich für eine
Happengrösse entscheiden. 4096 ist die StandardBuffergröße in PB, wenn Du
mehr möchteste, solltest Du ein vielfaches davon nehmen, z.B. 16 MB und
den FileBuffer hochsetzen.

Du kannst mit PeekB und PokeB arbeiten, jedoch wenn Du mit Pointern klar-
kommst, so ist das ein vielfaches schneller.

Verfasst: 17.05.2007 19:20
von String
Ich glaube die Sache mit den Pointern ist wohl das richtige.
Na dann werde ich mich da mal einarbeiten. Wollte ich sowieso schon längst.
Noch einmal Danke.