![]() |
große Textdateien in Stringlist laden
Hallo,
ich habe folgendes Problem: Ich versuche eine Datei auf einen bestimmten String zu durchsuchen. Die Datei ist ca. 1-4MB groß (Ein Spielstand). Das Problem ist jetzt, dass sich in der Stringlist nach dem Öffnen keine Strings befinden.(per count gezählt) Wenn ich zB eine kleine Textdatei mit 3 Zeilen lade, funktioniert alles wie gewünscht. Fehler werden keine gemeldet. Wenn die Datei zB in Notepad geöffnet wird kann ich über die Suche den entsprechenden String finden. Kann es sein, dass es da eine Größenbeschränkung gibt? Edit: Es ist übrigens eine .dat Datei, allerdings lässt sie sich mit Notepad öffnen, also nehme ich an, dass man auch Strings auslesen kann?
Delphi-Quellcode:
Das sind die ersten Zeilen der zu öffnenden Datei, vielleicht hilft es:
OpenDialog.Execute;
try dat := TStringList.Create; dat.LoadFromFile(OpenDialog.FileName); if pos(edit.text, dat.Text)=0 then result:=false; else result:=true; finally dat.Free; end; [quote]’ AIDDatabaseEntry ATTRTYPE int32 IsAvailable bool IsHidden bool IsInvented bool OVERLAYFILENAME string SYMBOLNAME string AnimatedRideInstanceE AIDDatabaseEntry managedobjectptr /quote] wenn ich mit memo.Lines.Add(dat.Strings[1]); versuche die Strings auszulesen, gibt es eine Fehler, da der Index nicht vorhanden ist. |
Re: große Textdateien in Stringlist laden
ZIP mal die Datei und häng sie als Attachment an deinen Beitrag.
|
Re: große Textdateien in Stringlist laden
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe die Datei angehängt. Eigentlich müsste die Endung .dat lauten, da aber nur txt erlaubt ist als Attachment habe ich sie umbenannt, sollte keinen Unterschied machen. Sorry für den Mehrfachpost, ich hatte eigentlich die Edit Funktion benutzt... :?:
Edit: Habe gerade einige Tests gemacht. Wenn ich in der IDE den Inhalt der Datei in zb ein Richedit kopiere, wird der Großteil abgeschnitten. Wenn ich den Text über den Quelltext einfüge wird es komplett übernommen. Ich vermute es liegt daran das es eine dat Datei ist und Steuerzeichen(?) enthält "ä @ 8 2Àä @ 8 .Àä @ 8 *À", irgendwo stehen allerdings Dateinamen und die will ich suchen, bzw. auslesen. Edit2: Wenn die Textdatei als UTF-8 gespeichert wird funktioniert es, aber wie wandle ich in Delphi Dateien in diese Kodierung um? |
Re: große Textdateien in Stringlist laden
De Index beginnt mit 0 und wenn keine Zeilenumbrüche in der Datei sind (hab jetzt noch nicht in die datei geguckt, dann gibt's nur eine Zeile ... halt die [0] ;)
|
Re: große Textdateien in Stringlist laden
Wenn ich diese Datei in meinem Texteditor öffne, so wird sie HEX Modus angezeigt. Will heissen: deine Datei enthält Sonderzeichen, und dann bist du mit TStringList auf der falschen Seite. TStringList benötigt Zeilenumbrüche, entweder als #13#10 oder #13.
Deshalb: benutze TFileStream. |
Re: große Textdateien in Stringlist laden
Herzlich willkommen in der Delphi-PRAXiS, elevance.
Um die in einer Binärdatei vorhandenen Strings zu extrahieren kannst du etwa so vorgehen:
Delphi-Quellcode:
Das sollte dir auch bei Sierra's Outpost helfen.
program Vis;
{$APPTYPE CONSOLE} uses SysUtils, Classes; const MIN_LENGTH = 3; var c: Char; s: string; stdIn: file of Char; visibleChars: set of Char; begin AssignFile(stdIn, ParamStr(1)); Reset(stdIn); AssignFile(output, ParamStr(2)); Rewrite(output); visibleChars := ['0'..'9', ' ', 'A'..'Z', 'a'..'z']; s := ''; while not Eof(stdIn) do begin Read(stdIn, c); if c in visibleChars then s := s + c else if Length(s) >= MIN_LENGTH then begin WriteLn(s); s := ''; end; end; CloseFile(output); CloseFile(stdIn); end. Freundliche Grüße |
Re: große Textdateien in Stringlist laden
Vielen Dank für die schnelle Hilfe :thumb: Mit der Methode von marabu funktioniert es schon recht gut, nur gibt es noch eine Frage:
Ich will die Datei ja nach Strings durchsuchen, die werden jetzt aber teilweise durch Zeilenumbrüche getrennt. Ich habe es jetzt so gelöst dass ich die Zeilenlänge (MIN_LENGTH) auf zB 500000 setzte, dadurch ist die Wahrscheinlichkeit hoch, dass nichts wichtiges verloren geht, zumal die gesuchten Werte immer mehrmals vorkommen, aber ich hätte gerne noch eine elegante Lösung, weiß da jemand was? |
Re: große Textdateien in Stringlist laden
Mit der MIN_LENGTH sagst du dem Programm, dass alle gefundenen Strings mit einer kleineren Länge nicht ausgegeben werden sollen. Du möchtest bestimmt lieber weitere Zeichen in den Set mit den sichtbaren Zeichen aufnehmen - insbesondere das Blank (#32) und eventuell ein paar Interpunktionszeichen. Mit MIN_LENGTH = 50000 dürfte gar keine Ausgabe mehr erzeugt werden.
|
Re: große Textdateien in Stringlist laden
Delphi-Quellcode:
funktioniert :-D das memo benutze ich nur während der Testphase, liege ich richtig dass eine Stringlist schneller wäre? Und noch zwei andere Fragen:
var
I: Integer; term:String; found:Boolean; begin visibleChars := ['0'..'9','_','-', 'A'..'Z', 'a'..'z']; s := ''; OpenDialog1.Execute; AssignFile(stdIn, opendialog1.FileName); Reset(stdIn); AssignFile(output, ExtractFilePath(ParamStr(0))+'temp.txt'); Rewrite(output); while not Eof(stdIn) do begin Read(stdIn, c); if c in visibleChars then s := s + c else if Length(s) >= MIN_LENGTH then begin Write(s); s := ''; end; end; CloseFile(output); CloseFile(stdIn); memo1.Lines.LoadFromFile(ExtractFilePath(ParamStr(0))+'temp.txt'); for I := 1 to length(edit.text) do begin if edit.text[i] in visibleChars then term:=term+edit.text[i]; end; found:=false; for I := 0 to memo1.Lines.Count-1 do begin if pos(term,memo1.Lines[i])>0 then found:=true; end; showmessage(BoolToStr(found)); end; - lässt sich der Vorgang etwas beschleunigen bzw. wie lässt sich die Gesamtgröße der Quelldatei berechnen um einen Fortschritt in Prozent zu berechnen. - und wie füge ich den Filterausdruck zB "#32" ein? Wie man zB eine Klammer einfügt habe ich verstanden, aber bei #32 gibt es einen Umwandlungsfehler. |
Re: große Textdateien in Stringlist laden
+ #32
Code:
(#32 ist ein Leerzeichen)
visibleChars := ['0'..'9','_','-', 'A'..'Z', 'a'..'z', [b][color=#ff0000]#32[/color][/b]];
// oder visibleChars := ['0'..'9','_','-', 'A'..'Z', 'a'..'z', [b][color=#ff0000]' '[/color][/b]]; Schneller ginge es, wenn du nicht ständig Strings verändern würdest und auch nicht nur Byteweise arbeitest. Dann brauchst du es doch nicht in eine temporäre Datei schreiben ... du kannst das gefilterte doch direkt in die StringList einfügen, oder besser erstmal in einen temporätren String. Ach ja, da du doch eh nur suchst, ginge es am schnellsten, wenn du garnicht erst filterst und dafür direkt in den Binärdaten suchst. Würde die ganzen Stringmanipulationen und alles Weitere ersparen. [add] Nicht getestet, aber es ich denk/hoff, daß keine Fehler drin sind.
Delphi-Quellcode:
Hier wäre auch noch der Vorteil, daß beim Auffinden des Suchwortes abgebrochen wird und nicht erst die gesamte Datei bearbeitet werden muß.
const BufferSize = 8192;
var S: String; i, AmtTransferred: Integer; found := false; S := ''; AssignFile(stdIn, opendialog1.FileName); Reset(stdIn); while not Eof(stdIn) do begin i := Length(S); SetLength(S, i + BufferSize); // weiteren Speicher reservieren (BufferSize) BlockRead(stdIn, @Buf[i + 1], BufferSize, AmtTransferred); SetLength(S, i + AmtTransferred); // Speicher entsprechend der gelesenen Daten anpassen (am Dateiende) if Pos(term, S) > 0 then begin found := true; Break; end; Delete(S, 1, Length(S) - Length(term)); // Speicher löschen, bis auf einen Teil, damit das end; // Suchwort auch über Blockgrenzen gefunden wird. CloseFile(stdIn); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 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