AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Suchen/Ersetzen in grossen Dateien

Ein Thema von hoika · begonnen am 31. Mai 2012 · letzter Beitrag vom 31. Mai 2012
Antwort Antwort
Seite 1 von 2  1 2   
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.269 Beiträge
 
Delphi 10.4 Sydney
 
#1

Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 13:00
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
Heiko
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 13:15
Weise den TMemoryStream einem TStringStream zu
Markus Kinzler
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#3

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 13:16
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:
  MyStringList.LoadFromFile(MyFilename);
  MyStringList.Text := StringReplace(MyStringList.Text,'<NAME>','<WhatEver>',[rfReplaceAll]);
  MyStringList.SaveToFile(MyFilename);
Ist zwar suboptimal, aber schnell genug sollte das sein...

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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#4

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 13:23
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
675 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 13:24
@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.
Das ist versionsabhängig. Hab ich vor Ewigkeiten mal in's QC gestellt, ist inzwischen gefixt (ticket 60730).

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.
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
844 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 13:51
Aber wenn schon das, besser gleich einen Aho-Corasick, um auch mal mehrere Begriffe in einem Durchlauf ersetzen zu können.
Wird zwar etwas OT, weil hier der Flaschenhals höchstwahrscheinlich nicht die Suche, sondern das Ersetzen ist (wenn nur nach einem Zeichen gesucht wird, bringen KMP, Boyer-Moore und Konsorten gar nichts ). Aber für die mehrfache Suche gibt es afaik deutlich bessere Algorithmen als Aho-Corasick. Ich habe sehr gute Erfahrungen mit Wu-Manber gemacht, der auch nicht furchtbar kompliziert zu implementieren ist.
The angels have the phone box.
  Mit Zitat antworten Zitat
CCRDude

Registriert seit: 9. Jun 2011
675 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 14:03
weil hier der Flaschenhals höchstwahrscheinlich nicht die Suche, sondern das Ersetzen ist (wenn nur nach einem Zeichen gesucht wird, bringen KMP, Boyer-Moore und Konsorten gar nichts ).
Einfach mal den Original-Post lesen Es geht um 6 Zeichen, und da Hoika schreibt, dass er die Datei Byte für Byte ausliest, ist eigentlich schon klar, daß der Flaschenhals das üble I/O und momentan noch weder die eigentliche Suche noch das Ersetzen ist

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.
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
844 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 14:20
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. ))
The angels have the phone box.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.269 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 15:04
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
Heiko

Geändert von hoika (31. Mai 2012 um 15:19 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#10

AW: Suchen/Ersetzen in grossen Dateien

  Alt 31. Mai 2012, 16:16
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 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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz