Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi 2 Gigabyte grosse Datei blockweise durchsuchen (https://www.delphipraxis.net/83153-2-gigabyte-grosse-datei-blockweise-durchsuchen.html)

tuebben 28. Dez 2006 13:46


2 Gigabyte grosse Datei blockweise durchsuchen
 
Hallo,

als Delphi-Noob stehe ich momentan vor der Aufgabe, sehr große Text-Dateien (bis zu 2 Gigabyte) nach bestimmten Schlüsselwörtern
durchsuchen zu müssen. Diese können sowohl im ASCII- als auch im Unicode-Format vorliegen.

Ich würde dann die Datei öffnen und blockweise einlesen. Jeden Block durchsuche ich nach dem Schlüsselwort und merke mir dann die
Position in der Datei. Bevor ich den nächsten Block lese, setze ich den Filepointer um ein paar Bytes zurück, damit ich
Schlüsselwörter, die zwischen 2 Blocks liegen auch erfassen kann.

Nun wollte ich an dieser Stelle nach einer geeigneten Vorgehensweise fragen. Einige Recherchen in diesem Forum ergaben, dass
anscheinend TFileStream das Mittel der Wahl ist. Ist das so korrekt? Würdet Ihr für die Aufgabenstellung ebenfalls TFileStream
benutzen?

Zum Merken der Positionen der Schlüsselwörter in der Datei würde ich ein Objekt benötigen, was einer VB-Collection (also eine
dynamische Liste, der man zur Laufzeit beliebig Items anhängen kann) gleichkäme. Welches Objekt würde ich dann in Delphi verwenden
können?

Danke im voraus & Grüße ... Peter

// Edit:

Wichtige Info noch als Nachtrag: Die zu durchsuchenden Dateien haben keinen Zeilenumbruch.
Ein zeilenweises Einlesen ist somit nicht möglich.

himitsu 28. Dez 2006 14:02

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Eventuell wären auch MemoryMappedFiles für dich geeignet ... dort kannst du sie datei stückchenweise in den Speicher mappen und ganz einfach in dem gemappten Speicher rumsuchen


Schau mal da ReadFileScatter/WriteFileGatter in den Dateianhang, dort sind auch andere Möglichkeiten zum Dateieinlesen gegeben (Win-API).



PS: TFileStream ist auch nur eine Klasse, welche intern (wie alle anderen Delphi-Funktionen/-Klassen) auf ReadFile/WriteFile (Win-API) zugreift.

Im MSDN / PSDK findest du genaueres zu den Funktionen.

alzaimar 28. Dez 2006 14:05

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Ein TFileStream-Objekt ist schon richtig. Als Liste würde ich eine TStringlist verwenden.

Wenn Du viel Zeit hast, dann reicht ein generisches Suchen, wobei ich zunächst den jeweils 1. Buchstaben mit den Schlüsselwörtern der Stringliste vergleichen würde, und erst wenn da ein Treffer ist, mal genauer hinschauen.

Wenn Du Dir etwas komplexere Algorithmen zutraust, dann schau mal nach KMP oder ähnlichen Verfahren, die solch 'Multi-Wort' Suche sehr effizient implementieren.

Wenn Du sehr lange Schüsselwörter hast, lohnt ein Blick auf Horspool, Boyer-Moore oder 'Quicksearch'.

Genaueres findest Du hier:

http://www-igm.univ-mlv.fr/~lecroq/string/index.html

Der_Unwissende 28. Dez 2006 14:06

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Hi,
dein Ansatz auf TFileStream zu setzen ist imho gar nicht schlecht, kannst du sehr einfach verwenden und spricht nichts ernsthaft gegen.

Was die Positionen und das dyn. Speichern angeht, hast du gleich mehrere Möglichkeiten. Die erste (von der ich dir gleich abraten möchte) besteht darin, dass du ein dyn. Array verwendest. Hier kannst du mittels setLength die Länge dyn. anpassen, was intern aber zum neu allozieren von Speicher und umkopieren der alten Daten führt (also ein eher großer Overhead). Hier kannst du natürlich einfach mehr Speicher reservieren als du benötigst (der Overhead pro Element sinkt entsprechend ab), musst dann allerdings natürlich auch verwalten wieviele Elemente tatsächlich benutzt werden.
Da gibt es eine Klasse TList, die nimmt dir genau das ab. Intern wird zwar ein Array verwendet, aber diese Klasse kümmert sich bereits um die Verwaltung der Größe (du musst nicht mehr machen als Elemente mit Add einfügen). TList speichert dabei einfach Pointer, hier kannst du also die Adresse beliebiger Daten ablegen (oder gleich die 32 Bit als Position missbrauchen).
Verwendest du wirklich Objekte (also Instanzen von Klassen), so kannst du auf TObjectList zurückgreifen. Im Prinzip funktioniert diese Liste wie TList, du kannst in ihr aber nur Objekte (Referenzen auf diese) speichern. Der Vorteil dabei liegt dann darin, dass jedes Objekt einen Destruktor haben muss, der sich um die Freigabe des Speichers kümmert. Die TObjectList kann somit auch aut. für die Freigabe aller gespeicherten Elemente sorgen, bei der TList musst du dich selbst darum kümmern.

Gruß Der Unwissende

Christian Seehase 28. Dez 2006 14:14

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Moin Peter,

Zitat:

Zitat von Der_Unwissende
was intern aber zum neu allozieren von Speicher und umkopieren der alten Daten führt

AFAIK aber nur dann, wenn die neue Länge grösser als die alte ist.

Der_Unwissende 28. Dez 2006 14:20

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Zitat:

Zitat von Christian Seehase
Moin Peter,

Zitat:

Zitat von Der_Unwissende
was intern aber zum neu allozieren von Speicher und umkopieren der alten Daten führt

AFAIK aber nur dann, wenn die neue Länge grösser als die alte ist.

Sorry, bin hier implizit davon ausgegangen, dass die Liste die der Threadsteller sucht wohl nur wächst und habe mich darauf bezogen. Zu dem anderen Fall kann ich nichts sagen, würde aber einfach mal sagen, dass du da mit hoher Wahrscheinlichkeit recht hast!

tuebben 30. Dez 2006 12:25

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Hallo,

vielen lieben Dank für die vielen und prompten Antworten! :-D

Leider kann ich momentan Eure Tipps nicht ausprobieren, weil mein Turbo Delphi nicht mehr startet.
Ich habe die letzten 2 Tage damit verbracht, der Ursache auf den Grund zu gehen, leider erfolglos. :cry:

Wenn ich ein neues VCL-Projekt starten will (mit F9), hängt sich TD einfach auf.
Die Prereqs sind alle installiert worden. So langsam bin ich mit meinem Latein am Ende.

Nochmals Danke & Grüße ... Peter

Christian Seehase 30. Dez 2006 14:06

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Moin Peter,

solltest Du es noch nicht gemacht haben, dann könntest Du zu diesem Problem einfach mal einen neuen Thread aufmachen.

tuebben 31. Dez 2006 13:31

Re: 2 Gigabyte grosse Datei blockweise durchsuchen
 
Zitat:

Zitat von Christian Seehase
solltest Du es noch nicht gemacht haben, dann könntest Du zu diesem Problem einfach mal einen neuen Thread aufmachen.

[X] Done ;-)

Ich wollte vorher noch einige Sachen ausprobieren, bevor ich Euch damit belästige.

Grüße ... Peter


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 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