![]() |
Suchen/Ersetzen in grossen Dateien
Hallo #,
ich habe hier eine Datei (DOC, RTF ...), dort steht z.B. <NAME> drin. Ich möchte das <NAME> jetzt ersetzen. Bisher lese ich die Datei binär Byte für Byte aus, suche nach < bis ich ein > habe und schreibe sie binär wieder. Ist nicht mein Code. Bei grossen Datei dauert das Ersetzen ewig. Jetzt dachte ich daran, die Datei in einen TMemoryStream zu packen, von dort in einen String und dann das ersetzen per StringReplace zu machen. 2 Fragen: Wie bekomme ich die Datei aus dem TMemoryStream in einen String? Geht das überhaupt so einfach (Stichwort #0 in der Datei) Und wie bekomme ich den String wieder in eine Datei zurück ? Oder sollte ich das lieber per PChar machen ? Hilfe ! ;) Danke Heiko |
AW: Suchen/Ersetzen in grossen Dateien
Weise den TMemoryStream einem TStringStream zu
|
AW: Suchen/Ersetzen in grossen Dateien
Du könnstest einen Boyer-Moore, KMP oder Quicksearch-Algorithmus implementieren und den eben in einem Bytestream suchen lassen.
Aber wenn es sich eh um RTF bzw. TXT handelt, wieso machst Du Dir dann überhaupt um 0-Bytes Sorgen und nimmst nicht einfach das hier:
Delphi-Quellcode:
Ist zwar suboptimal, aber schnell genug sollte das sein...
MyStringList.LoadFromFile(MyFilename);
MyStringList.Text := StringReplace(MyStringList.Text,'<NAME>','<WhatEver>',[rfReplaceAll]); MyStringList.SaveToFile(MyFilename); Alternativ sollte ein TStringStream dein Freund sein bzw. werden. @mkinzler: Ich weiss nicht, ob StringReplace auf die Stringlänge schaut, oder bis zum ersten #0 Byte geht... Aber dann wäre ja meine Idiotenlösung auch für den Arm. |
AW: Suchen/Ersetzen in grossen Dateien
Es kommt drauf an, wie ersetzt wird.
Wird jedes Stück einzeln ersetzt und immer wieder alles nachfolgende verschoben, dann muß es zwangsläufig langsam sein. Wenn man alles in eine andere Datei / einen anderen speicherblock kopiert, dessen Größe (beim Speicherblock) vorher berechnet wurde und dann wird nur noch das unveränderte rüberkopiert, und dazwischen das zu Ersetzende eingefügt, dann geht es schneller. Bei einer Datei könnte man z.B. vorher alles suchen, sich die Positionen merken und - wenn der Ersatztext länger ist, dann fängt man von hinten an einzufügen (vorher die Datei-/Blockgröße anpassen) - wenn Er kürzer ist, dann eben von vorne (nachher die Datei-/Blockgröße anpassen). (Gleiches gilt für eine Inplace-Ersetung im Speicherblock/RAM) Für StringReplace hatte ich vor langem mal einen kleinen Code veröffentlicht, welcher das etwas optimiert. |
AW: Suchen/Ersetzen in grossen Dateien
Zitat:
![]() Zum Thema Boyer Moore: die zwei am häufigsten zu findenden Delphi-Implementierungen, die ich im Netz gefunden habe, habe selten auftretende Fehler. Lieber selber implementieren. Aber wenn schon das, besser gleich einen Aho-Corasick, um auch mal mehrere Begriffe in einem Durchlauf ersetzen zu können. |
AW: Suchen/Ersetzen in grossen Dateien
Zitat:
|
AW: Suchen/Ersetzen in grossen Dateien
Zitat:
Aber: nach Umstellung auf blockweise Verarbeitung ist bei 6 Zeichen ja schon was rauszuholen. Kommt halt drauf an, um wie viele dieser Dateien und wie automatisiert das gehen mag, ob sich der Aufwand lohnt. AC vs. (M)WM: "besser" ist immer relativ, muss man imo einzeln abstimmen, ob Geschwindigkeit oder Speicherbedarf wichtiger sind. War ja aber auch nur ein Beispiel, da so ein Template-System ja schnell mal auf mehr als eines wächst. |
AW: Suchen/Ersetzen in grossen Dateien
Ich hatte das so verstanden, dass "NAME" variabel ist und daher nur nach den umschließenden "<" und ">" gesucht wird. Ansonsten kann man da natürlich schon mit BM was rausholen. :)
(Das byteweise auslesen der Datei habe ich tatsächlich überlesen. Aber das ist ja nun wirklich eine extrem doofe Idee. (Ist ja nicht sein Code, dann darf ich das hier hoffentlich sagen. :stupid: )) |
AW: Suchen/Ersetzen in grossen Dateien
Hallo,
danke, danke ;) Es sind auch DOC dabei, deswegen die Frage nach dem #0. <NAME> war nur ein Bsp., die Datei wird einmalig durchlaufen, da können noch mehr Kenner drinstehn. Da ich hier nur D2007 zur Verfügung habe, klappt das StringReplace leider nicht mit #0 ;( (der QC ist zwar closed, aber ich habe das Bsp. mal ausprobiert, bei mir wird nicht alles ersetzt). Heiko |
AW: Suchen/Ersetzen in grossen Dateien
PS:
.DOC ... die alten Binärdateien oder das neue gezippte XML ... da muß man ein bissl aufpassen, wobei das neue Format sich doch eigentlich .DOCX nennt :gruebel: und im XML nach < und > zu suchen könnte auch etwas unhandlich werden. Bei den binären Dateien sollte man besser nicht die Strucktur verändern, also keine Ersetzungen mit unterschiedlichen längen, da dann das Dateiformat schnell mal zerschossen ist. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:32 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