Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Eigenes Zeichen für Zeilenende bei ReadLN (https://www.delphipraxis.net/174953-eigenes-zeichen-fuer-zeilenende-bei-readln.html)

Luckie 21. Mai 2013 15:23

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Ja und? Wozu hast du denn den Speicher in deinem Rechner? Ich meine, du kannst das ganze natürlich mit MemoryMappedFiles lösen, aber wozu der Aufwand in Gefilden von 200 bis 300 MB?

Meine Idee:
1. Lade Datei in StringListe
2. Gehe die Zeilen der StringListe durch
3. Wenn am Anfang einer Zeile kein "$" gefunden, dann kopiere die Zeile in eine zweite StringListe
4. Wenn am Anfang einer Zeile "$" gefunden (Jetzt weiß ich nicht, was mit dieser Zeile passieren soll. Das musst du wissen.), dann speichere die zweite StringListe ab, ode rmach was mit ihrem Inhalt
5. Wenn das geschehen gehe die Zeilen der ersten StringListe weiter durch
6. goto 3

Perlsau 21. Mai 2013 15:24

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Zitat:

Zitat von Ginko (Beitrag 1215948)
Es soll auf der Seite im Text gesucht werden, allerdings benötige ich zum Suchergebnis zusätzlich Informationen, die am Ende einer Seite stehen, dehalb soll immer eine ganze Seite eingelesen werden.

Es soll also immer nur auf einer Seite gesucht werden? Wieso denn das? Möchtest du nicht im gesamten Textdokument nach deinem gesuchten Text fahnden?

Zitat:

Zitat von Ginko (Beitrag 1215948)
Ich habe es jetzt erstmal so gelöst das ich einfach mal alle Linebreaks mit StringReplace gelöscht habe und nur das § Zeichen (bzw #12) durch einen Linebreak ersetzt habe. Allerdings geht mir dann die ursprüngliche Strukur verloren...

Na ist doch klar: Wenn du die Struktur eines Textes zerstörst, dann geht sie verloren. Wenn's regnet, wird man naß ...

Ginko 21. Mai 2013 15:29

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Ja es soll im ganzen Text gesucht werden, Missverständnis.
Allerdings soll bei einem Fund, Informationen vom Ende der Seite (Seitenzahl etc.) an das Suchergebnis angehängt werden. Deshalb brauch ich bei ReadLn immer den Abschnitt bis zum Ende einer Seite... (Weil ich die Datei Zeilenweise durchsuche).

Meine obige Lösung mit Stringreplace ist nur ein Übergangslösung. Für die reine Suche reicht sie aber vollkommen.

Luckie 21. Mai 2013 15:34

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Hast du dir mal meinen Vorschlag näher angeguckt? Dann pack die Seitenende-Zeile noch mit in die zweite StringListe. Durchsuche die zweite StringListe und die zusätzlichen Informationen findest du dann immer in der letzten Zeile der zweiten StringListe.

Ginko 21. Mai 2013 15:36

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Ich schau mir das mal noch genauer an. Muss jetzt aber erstmal weg. Danke bis hier für die ANtworten.

nahpets 21. Mai 2013 15:40

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Hallo,

schau Dir bitte mal TFileStream genau an.

Dann liest Du damit "zeichenweise". Immer wenn Du auf #12 stößt, weißt Du, dass eine Seite zuende ist.

Ich versuche es mal mit Pseudocode:
Code:
erstelle eine Stringliste
erstelle einen Memorystream
erstelle einen Filestream
wiederhole
  lese ein Zeichen aus dem Filestream
  ist Zeichen = #12
    kopieren den memorystream in eine Stringliste
    // hier enthält die Stringliste nun genau eine Seite
      mache hier die erforderlichen Arbeiten für diese Seite
    leer Stringliste
    leere memeorystream
  ist Zeichen <> #12
    schreibe zeichen in memeorystream
wiederhole bis Dateiende
// Erforderlich für die letzte Seite, falls die nicht mit #12 enden sollte.
ist der Memorystream nicht leer
  kopieren den memorystream in eine Stringliste
  // hier enthält die Stringliste nun genau eine Seite
    mache hier die erforderlichen Arbeiten für diese Seite
Ende

jaenicke 21. Mai 2013 15:42

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Wie wäre es mit meinem entsprechenden Reader?
http://www.delphipraxis.net/151898-s...ei-reader.html
Eine .reg Datei dieser Größe habe ich damit inkl. Parsen in unter 5 Sekunden in einem Baum angezeigt bekommen.

Bernhard Geyer 21. Mai 2013 16:16

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Zitat:

Zitat von Ginko (Beitrag 1215953)
Dann hätte ich 200MB Speicherverbrauch wenn ich die ganze Datei in eine Stringlist laden würde...

Nein. Eher bis zu 600 MB

200 MB für die Datei und jedeils 2 Byte (Unicode) für jedes Zeichen während des Aufbaus der Ergebnisliste.
AFAIK arbeitet hier die Delphi-Implementierung nicht gerade Speicherschonend.

Perlsau 21. Mai 2013 16:40

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Zitat:

Zitat von Luckie (Beitrag 1215951)
Er ist wohl der Meinung, dass eine StringListe für so große Dateien nicht geeignet wäre.

Vielleicht stimmt das ja auch:

Eben hatte ich einen Testdurchlauf gestartet mit einer ca. 285 MB großen Textdatei. Beim Versuch, diese Datei (nicht Zip einlesen, sondern vorher entpacken) direkt in eine Stringliste einzulesen, erhalte ich nach kurzer Zeit die Meldung, ich hätte zu wenig Arbeitsspeicher:
Exception der Klasse EOutOfMemory mit der Meldung 'Zu wenig Arbeitsspeicher' aufgetreten.
In meinem Rechner sind 4 GB Ram verbaut. Geöffnet sind ein Dateimanager, Seamonkey, Thunderbird und RadStudio 2009 nebst im Debug-Mode laufender Exe. Das kann's doch nicht sein :?:

Delphi-Quellcode:
procedure TForm1.Button_TextClick(Sender: TObject);
Var
   Liste : TStrings;

begin
     IF NOT OpenDlg.Execute THEN Exit;
     Liste := TStringList.Create;

     Try
       Liste.LoadFromFile(OpenDlg.FileName);
     Finally
       Liste.Free;
     End;
end;
Lese ich dagegen die Textdatei via ReadLn ein und weise dabei jedesmal der Stringliste die eingelesene Zeile zu, komme ich auf 7.654.474 Zeilen, die sich am Ende in der Stringliste befinden. Das verstehe ich nicht: Beim direkten Einlesen ist der Speicher angeblich zu klein, beim Zuweisen über ReadLn paßt's dann wieder rein ...
Delphi-Quellcode:
procedure TForm1.Button_TextClick(Sender: TObject);
Var
   Liste : TStrings;
   f    : TextFile;
   Zeile : String;
begin
     IF NOT OpenDlg.Execute THEN Exit;
     Liste := TStringList.Create;
     AssignFile(f,OpenDlg.FileName);
     Reset(f);

     Try
       WHILE NOT EOF(f) DO
       BEGIN
         ReadLn(f,Zeile);
         Liste.Append(Zeile);
         Label_Anzahl.Caption := IntToStr(Liste.Count);
         Application.ProcessMessages;
       END;
     Finally
       Liste.Free;
       CloseFile(f);
       Label_Anzahl.Caption := Label_Anzahl.Caption + ' ' + Zeile;
     End;
end;
Es erfolgt keine Fehlermeldung, alle Zeilen der Datei wurden in die Stringliste übertragen. Wie kann es also sein, daß beim direkten Befüllen der Stringliste eine Meldung erscheint, der Arbeitsspeicher würde nicht ausreichen?

Eben erhalte ich die Mitteilung, daß die erste Procedure mit Liste.LoadFromFile, wenn sie mit XE2 kompiliert wurde, fehlerfrei arbeitet.

Uwe Raabe 21. Mai 2013 17:55

AW: Eigenes Zeichen für Zeilenende bei ReadLN
 
Zitat:

Zitat von Perlsau (Beitrag 1215978)
In meinem Rechner sind 4 GB Ram verbaut. Geöffnet sind ein Dateimanager, Seamonkey, Thunderbird und RadStudio 2009 nebst im Debug-Mode laufender Exe. Das kann's doch nicht sein :?:

Erstmal hat eine 32-Bit-Anwendung nur maximal 2GB Speicher zur Verfügung und dann getht TStringList.LoadFromFile da schon ziemlich verschwenderisch mit dem Speicher um. Die Datei hat knapp 300MB, die zunächst als TBytes geladen werden. Dann schlägt das Encoding zu, das da nochmal die doppelte Menge drauf legt (wegen Unicode) und die Zeichen in einem Character Array ablegt (sind dann schon fast 900MB). Das nachfolgende Erzeugen des Unicodestring (600MB) schlägt dann fehl, weil offenbar der Speichermanager nicht mehr mitspielt (VirtualAlloc schlägt fehl).

Als 64-Bit funktioniert es dann aber.

Man könnte jetzt natürlich TStringList ableiten, LoadFromStream überschreiben und für große Dateien effizienter implementieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:45 Uhr.
Seite 3 von 5     123 45      

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