![]() |
Binär ersetzen / binäre Suche
Hallo.
Ich möchte ein gewissen Binär-Suchmuster (mit enthaltenen 00h's) durch ein anderes Suchmuster der selben Länge in einer Datei ersetzen. Ich habe unter Google und hier in der Suche keine Funktion gefunden, die eine binäre Suche innerhalb einer Datei bzw. eines Streams durchführt. Da ich ein Muster mit der Länge x Byte durch ein Muster der Länge x Byte ersetzen möchte, besteht die Problematik nicht unbedingt beim Ersetzen, sondern bei dem Aufsuchen der Position(en) innerhalb des Streams. Hat jemand eine Idee, wie ich eine binäre Suche realisieren kann? Gruß blackdrake |
Re: Binär ersetzen / binäre Suche
Hi,
Suche nach einem Char? Das entspricht doch 00h bis FFh. Also denke ich, wenn man für den String ein einzelnes Char angiebt sollte s doch klappen. Hab ich aber so nicht getestet. Ähm, oder doch? Hatte letztens #13 und #10 suchen und ersetzen lassen. Das sollte doch klappen. Die frage ist, ob man die Daten aus dem Stream in eine StringList bekommt. Gruß oki |
Re: Binär ersetzen / binäre Suche
Hallo.
StringList? Wäre nicht sinnvoll, da die Datei zu 95% aus binären Zeichen besteht. Ich müsste die Datei in einen Stream laden. Und das Problem liegt darin, ein binäres Muster (sagen wir mal #00 #01 #02 #03 #04) zu suchen und zu ersetzen. Ich habe aber keine Ahnung, wie ich die Vorkommen dieses Musters innerhalb eines binären Streams ermitteln kann. Gruß blackdrake |
Re: Binär ersetzen / binäre Suche
ok, ich dachte du suchst die Übereinstimmung eines Bytes. Das wäre dann wie ein Char und mit StringReplace könnte mann es in einer Stringlist bearbeiten.
Dann denke ich, kannst du den Stream byte-weise lesen. erste Vorkommen 00h, merken, nächster muss 01h sein, wenn nicht Merker löschen .... Ist der komplette Sucheintrag vorhanden, ersetzen. Das kann dann alles in einem Temp-Stream erfolgen. Gruß oki |
Re: Binär ersetzen / binäre Suche
Hallo oki.
Danke für den Tipp. Erscheint zwar logisch, jedoch wäre diese Lösung a) nicht dynamisch (da kein beliebiges Such/Ersatz-Muster angegeben werden kann. Jedoch ist mein Beispiel statisch) b) ziemlich langsam, da die Datei ca. 1 MB groß ist. Wenn man eine 1 MB große Datei byteweiße abgehen und die vorrangehenden Bytes auf das Suchmuster überprüfen würde, wäre das sehr uneffektiv. Gibt es keine bessere Lösung (z.B. eine solche, wie sie in Hex-Editoren bei der Ersatz-Funktion angewandt wird)? Die Methode des byteweisen Abtastens des Streams würde ich nur anwenden, wenn sich keine bessere Methode anbieten würde. Gruß blackdrake |
Re: Binär ersetzen / binäre Suche
Hi,
also was besseres fällt mir nicht ein. Dann muß wohl jemand anders ran. Assembler ist vielleicht ne Lösung. Gruß oki |
Re: Binär ersetzen / binäre Suche
Moin Daniel,
lies die Datei doch mittels TFileStream in einen String ein, und ersetzte die Zeichen mit StringReplace. Das müsste eigentlich funktionieren, und 1MB ist ja nun nicht sooo gross. |
Re: Binär ersetzen / binäre Suche
Hallo.
Funktioniert leider nicht.
Delphi-Quellcode:
Es funktioniert, wenn ich eine Zeichenkette vom Anfang suche und ersetze. Wenn ich jedoch etwas suchen und ersetzen will, was vom Dateianfang durch ein Null-Byte (#00h) getrennt ist, passiert nichts.
procedure TForm1.Button1Click(Sender: TObject);
var x: TFileStream; s: string; begin x := TFileStream.Create('test.xyz', fmOpenReadWrite or fmShareDenyWrite); try x.Position := 0; setlength(s, x.Size-1); x.Read(s[1], x.Size-1); s := StringReplace(s, #$0E, #$7D, [rfReplaceAll]); x.Position := 0; x.Write(s[1], length(s)) finally x.free; end; close; end; 12 34 56 0E 78 00 12 00 ... -> 12 34 56 7D 78 00 12 00 (OK) 12 34 56 88 78 00 0E 00 ... -> 12 34 56 88 78 00 0E 00 (Fehler) Scheinbar arbeitet StringReplace() intern mit PChar's, was dazu führen könnte, dass #00h's als Schlussbegrenzung angesehen werden. Dadurch ist StringReplace() scheinbar nicht Binary-Safe, obwohl Strings von Grund auf Binary-Safe sind. Oder hab ich was falsch gemacht? Gruß blackdrake |
Re: Binär ersetzen / binäre Suche
sowas wird byteweise gemacht.
Wenn du beispielsweise nach 12 34 56 0E 78 00 12 00 suchst gehst du byteweise alles durch bis du 12 gefunden hast. Wenn du ein 12 gefunden hast schaust du ob danach ein 34, dann ein 56 etc. kommt. Wenn dann irgendwas nicht mehr stimmt musst du an der stelle wo du die 12 (erstes zeichen) gefunden hast wieder nach der nächsten 12 suchen. Soviel zur Theorie. Die Praxis sollte jeder Programmierer selbst hinnbekommen. |
Re: Binär ersetzen / binäre Suche
Moin Daniel,
ich hab' mal in die Sourcen geschaut. Leider verwendet StringReplace AnsiPos, das wiederum AnsiStrPos und somit, wie Du schon sagtest, PChar, verwendet :wall: In Deinem Falle müsste das aber mit Pos und PosEx lösbar sein. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz