Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Anzahl Zeilen in einem Textfile (https://www.delphipraxis.net/22487-anzahl-zeilen-einem-textfile.html)

TomDooley 18. Mai 2004 07:46


Anzahl Zeilen in einem Textfile
 
Hallo

Ich möchte die Anzahl Zeilen in einem Textfile auslesen (Typ: textfile).

Sollte das nicht mit
Delphi-Quellcode:
anzZeilen := FileSize(filename);
funktionieren?? Mir werden aber immer genau die Hälfte der Zeilen ausgegeben.... :gruebel:

Gruss

Tom

Anubis 18. Mai 2004 07:54

Re: Anzahl Zeilen in einem Textfile
 
also laut Hilfe
Zitat:

Hinweis
FileSize kann nicht für Textdateien verwendet werden.

TomDooley 18. Mai 2004 07:58

Re: Anzahl Zeilen in einem Textfile
 
hmm... das heisst alle Zeilen mit ReadLn einlesen und inkrementieren bis EoF erreicht?

MarcusB 18. Mai 2004 08:01

Re: Anzahl Zeilen in einem Textfile
 
Ist vielleicht umständlich, aber dürfte funzen :

Delphi-Quellcode:
var
  txt: textfile;
  anzahl: integer;
begin
  AssignFile(txt, 'xyz.txt');
  reset(txt);
  while not EOF(txt) do
  begin
    inc(anzahl);
  end;
  CloseFile(txt);
 
  ShowMessage(IntToStr(anzahl));
end;
Gruß

MarcusB

toms 18. Mai 2004 08:02

Re: Anzahl Zeilen in einem Textfile
 
Hi,

Probier mal diese Funktion:

Delphi-Quellcode:
function TextLineCount_BufferedStream(const Filename: TFileName): Integer;
const
  MAX_BUFFER = 1024 *1024;
var
  oStream: TFileStream;
  sBuffer: string;
  iBufferSize: Integer;
  iSeek: Integer;
  bCarry: Boolean;
begin
  Result := 0;
  bCarry := False;
  oStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    SetLength(sBuffer, MAX_BUFFER);
    repeat
      iBufferSize := oStream.Read(sBuffer[1], MAX_BUFFER);
      if iBufferSize <= 0 then
        break;
      {Skip LFs that follow a CR - even if it falls in seperate buffers}
      iSeek := 1;
      if bCarry and (sBuffer[1] = #10) then
        Inc(iSeek);
      while iSeek <= iBufferSize do
      begin
        case sBuffer[iSeek] of
        #10:
          Inc(Result);
        #13:
          if iSeek = iBufferSize then
            Inc(Result)
          else
          if sBuffer[iSeek + 1] <> #10 then
            Inc(Result)
          else
          begin
            Inc(Result);
            Inc(iSeek);
          end;
        end;
        Inc(iSeek);
      end;
      {Set carry flag for next pass}
      bCarry := (sBuffer[iBufferSize] = #13);
    until
      iBufferSize < MAX_BUFFER;
  finally
    FreeAndNil(oStream);
  end;
end;

Gollum 18. Mai 2004 08:13

Re: Anzahl Zeilen in einem Textfile
 
Hallo,

wie wäre es damit?
Delphi-Quellcode:
var sl:TStringList;
...
sl:=TStringList.Create;
try
  sl.LoadFromFile('c:\test.txt');
  ShowMessage(Format('Datei enthält %d Zeilen.', [sl.Count]));
finally
  sl.Free;
end; // try

IngoD7 18. Mai 2004 08:22

Re: Anzahl Zeilen in einem Textfile
 
Jo, bei Textfiles empfiehlt der Apotheker TStringList. :wink:

@MarcusB
Dein Code zählt sich tot. 8)

TomDooley 18. Mai 2004 13:30

Re: Anzahl Zeilen in einem Textfile
 
Danke. Das mit der Stringliste hört sich ganz gut an... Jetzt dazu noch ein kleines Problem: Wie kann ich eine Strinliste mit dem Inhalt einer geöffneten Datei befüllen? Also so in etwas:

Delphi-Quellcode:
WriteLn(File,Text); //File befüllen
meineStringListe.ladeVon(File); //File in meineStrinListe laden
anzahl := meineStringListe.count; //Zeilen zählen
Oder muss ich das File erst schliessen? Oder jede Zeile mit ReadLn aus File lesen (ist etwas umständlich nur um an die Anzahl zu kommen....)

es dankt und grüsst

Tom

s14 18. Mai 2004 13:33

Re: Anzahl Zeilen in einem Textfile
 
Gollum hat mit seinem Beitrag die Frage bereits, mit Code-Beispiel, beantwortet :wink:

TomDooley 18. Mai 2004 13:50

Re: Anzahl Zeilen in einem Textfile
 
:gruebel: Gollums Datei ist aber geschlossen und nicht wie meine Datei geöffnet... Geht das trotzdem irgendwie?

Luckie 18. Mai 2004 13:52

Re: Anzahl Zeilen in einem Textfile
 
Probier es aus. Aber wenn man eine Datei nicht mehr braucht, sollte man sie generell sofort schließen. Was hindert dich also daran, sie erst zu schließen und dann die Anzahl der Zeilen zu ermitteln?

TomDooley 18. Mai 2004 13:56

Re: Anzahl Zeilen in einem Textfile
 
ich möchte die Anzahl Zeilen am Schluss derselben Datei einfügen... (Theoretisch könnte ich sie natürlich schliessen, auslesen und wieder öffnen aber wenn's nicht unbedingt sein muss...)

Luckie 18. Mai 2004 13:58

Re: Anzahl Zeilen in einem Textfile
 
Wie schreibst du denn rein? Zähl duch die Aufrufe von writeln mit und schreib mit der letzten writeln-Anweisung die Zeilen rein.

IngoD7 18. Mai 2004 14:11

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von TomDooley
:gruebel: Gollums Datei ist aber geschlossen und nicht wie meine Datei geöffnet... Geht das trotzdem irgendwie?

Die Verwendung einer TStringList hat mit öffnen und schließen einer Datei nichts zu tun.

Und zur späteren Thematik:
Wenn du etwas der Datei anfügen möchtest, kannst du es der TStringList anfügen und danach auf quasi demselben Wege (via SaveToFile) wieder zurück auf die Platte schreiben.

Sieh in Online-Hilfe bei TStringList, was damit alles schönes möglich ist. Danach wirst du keine Textdateien mehr öffnen und schließen wollen. :zwinker:

TomDooley 18. Mai 2004 14:36

Re: Anzahl Zeilen in einem Textfile
 
loadFromFile erwartet einen String (FileName)... ich habe jedoch eine geöffnete Datei (Typ Text). Ich denke das geht so nicht... Das mit dem WriteLn zählen würde aber wohl funktionieren... Dazu aber noch etwas: Wenn ich die Anzahl tatsächlich mit dem letzen WriteLn schreiben möchte, aber nicht am Schluss der Datei sondern am Anfang... Kann ich das mit Seek(Datei, 0) und dann eine WriteLn machen?

IngoD7 18. Mai 2004 15:22

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von TomDooley
loadFromFile erwartet einen String (FileName)... ich habe jedoch eine geöffnete Datei (Typ Text).

Dann öffne die Datei gar nicht erst, sondern mache alles mit TStringList! :roll:

Und ich wiederhole, dass wenn du TStringList lieben und anwenden gelernt hast, du keine Textdatei jemals wieder öffnest. :twisted:

Achja, und für den Fall, dass ich ins Leere rede - zu deinen Seek- und WriteLn-Fragen: Probier's einfach aus. Geht wahrscheinlich schneller, als hier eine Antwort zu bekommen. :zwinker:

MarcusB 18. Mai 2004 16:12

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Dein Code zählt sich tot.
OH wie peinlich! :oops:

Vielleicht noch ein readln reinpfrimeln :wink:

Aber hat sich ja eh erledigt, die Lösung mit der Stringlist ist prima!

TomDooley 18. Mai 2004 16:15

Re: Anzahl Zeilen in einem Textfile
 
ok, ich probier alles mal aus....

das mit der StringList begreife ich allerdings nicht so ganz... irgendwie muss ich meine Daten ja weiter geben können :roll:

alcaeus 18. Mai 2004 16:18

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von TomDooley
das mit der StringList begreife ich allerdings nicht so ganz... irgendwie muss ich meine Daten ja weiter geben können :roll:

:wall: :wall: :wall:

Also, du lädst die Datei in eine Stringlist, manipulierst sie da nach belieben, und dann schreibst du sie mit
Delphi-Quellcode:
StringList1.SaveToFile(<Dateiname>);
wieder hinaus. Die Datei liegt dann als Plaintext-Datei auf der Festplatte, ich versteh dein Problem irgendwie nicht mehr.

[add]Das Stichwort hier lautet Delphi-OH[/add]

Jens Schumann 18. Mai 2004 17:17

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von IngoD7
Zitat:

Zitat von TomDooley
loadFromFile erwartet einen String (FileName)... ich habe jedoch eine geöffnete Datei (Typ Text).

und ich wiederhole, dass wenn du TStringList lieben und anwenden gelernt hast, du keine Textdatei jemals wieder öffnest. :twisted:

Da bin ich mir nicht so sicher. Ich habe es öfter mit TxT-Dateien zu tun, die zwischen 300 und 500 MB groß sind. Da nehme ich doch lieber ne normale TextFile mit Reset und Readln und so anstatt TStringList.

IngoD7 18. Mai 2004 19:28

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von Jens Schumann
Da bin ich mir nicht so sicher. Ich habe es öfter mit TxT-Dateien zu tun, die zwischen 300 und 500 MB groß sind. Da nehme ich doch lieber ne normale TextFile mit Reset und Readln und so anstatt TStringList.

Gut, solche Monsterdateien habe ich nun nicht bedacht - zugegeben. Da fehlt mir auch jegliche Erfahrung. Sollten aber die Ausnahme darstellen, oder?
Obwohl :gruebel: , ab welcher Datei-Größe würdest du denn von TStringList abweichen?

Jens Schumann 18. Mai 2004 21:00

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von IngoD7
Zitat:

Zitat von Jens Schumann
Da bin ich mir nicht so sicher. Ich habe es öfter mit TxT-Dateien zu tun, die zwischen 300 und 500 MB groß sind. Da nehme ich doch lieber ne normale TextFile mit Reset und Readln und so anstatt TStringList.

Gut, solche Monsterdateien habe ich nun nicht bedacht - zugegeben. Da fehlt mir auch jegliche Erfahrung. Sollten aber die Ausnahme darstellen, oder?
Obwohl :gruebel: , ab welcher Datei-Größe würdest du denn von TStringList abweichen?

Weiss ich auch nicht so genau. Evt ab 3 MB

GuenterS 18. Mai 2004 21:09

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von Jens Schumann
Zitat:

Zitat von IngoD7
Zitat:

Zitat von TomDooley
loadFromFile erwartet einen String (FileName)... ich habe jedoch eine geöffnete Datei (Typ Text).

und ich wiederhole, dass wenn du TStringList lieben und anwenden gelernt hast, du keine Textdatei jemals wieder öffnest. :twisted:

Da bin ich mir nicht so sicher. Ich habe es öfter mit TxT-Dateien zu tun, die zwischen 300 und 500 MB groß sind. Da nehme ich doch lieber ne normale TextFile mit Reset und Readln und so anstatt TStringList.


[OT]
300 - 500 MB ... Dein Tagebuch? *fg*
[/OT]

Hansa 18. Mai 2004 21:13

Re: Anzahl Zeilen in einem Textfile
 
Ich habe das Thema jetzt nur überflogen, aber anfangs gings hier drum :

Zitat:

Ich möchte die Anzahl Zeilen in einem Textfile auslesen (Typ: textfile).
Delphi-Quellcode:
var d : TextFile;
    i : integer;
begin
  i := 0;
  AssignFile (d,'meintext.txt');
  reset (d);
  while not eof (d) do begin
    readln (d);
    i := i + 1;
  end;
  showmessage (IntToStr (i))+ ' Zeilen');
end.
Die paar Zeilen sind das kompette Programm !! Ohne Stringlist und sonstigen Firlefanz. Und 500 MB :shock: sind dem auch egal.

IngoD7 19. Mai 2004 10:24

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von Hansa
Die paar Zeilen sind das kompette Programm !! Ohne Stringlist und sonstigen Firlefanz.

Tja, und die paar Zeilen aus Gollums Posting sind noch kompakter - sogar mit, oder besser, wegen dem "Firlefanz". :roll:

SirThornberry 19. Mai 2004 12:05

Re: Anzahl Zeilen in einem Textfile
 
Sorry, aber irgendwie macht ihr das ganze ziemlich unperformant. Wozu immer Readln? Da wird erst geprüft wo ein Zeileumbruch ist und dann erst in den buffer eingelesen.

Ich würde die datei per TFileStream öffnen und dann in einer schleife die gesamte datei durchgehen und prüfen wann ein #13 und anschließend ein #10 kommt. Die Zeilenanzahl kann dann einfach angehängt werden in dem die datei im append-modus geöffnet wird

Natürlich auch nicht jedes zeichen einzeln lesen sondern einen ziemlich großen buffer einmal allozieiren und den buffer dann durchgehen...

TomDooley 19. Mai 2004 12:30

Re: Anzahl Zeilen in einem Textfile
 
Hallo

Anschliessend mal den Code, wie ich ihn jetzt verwende... Ich hoffe er ist verständlich. Funktioniert, aber ist vielleicht nicht so sauber:
Delphi-Quellcode:
OFile : Textfile;


AssignFile(OFile,FileName);
Rewrite(OFile);
TmpStr := 'abc';
WriteLn(OFile,TmpStr); //manchmal müssen hier mehrer Zeilen eingefügt werden
for Lp := 0 to StringListe.Count-1 do
  Writeln(OFile, StringListe.Strings[Lp]);
Reset(OFile);
while not Eof(OFile) do begin
  ReadLn(OFile, TmpStr);
  StringListe2.Add(TmpStr);
end;
TmpStr := 'abc'; //abc = AnzahlZeilen --> von StringListe + obigen Anz. TmpStr abhängig
StringListe2.Insert(0, TmpStr); //abc muss unbedingt am Anfang eingefügt werden
Rewrite(OFile);
for Cnt := 0 to StringListe2.Count-1 do
  Writeln(OFile, StringListe2.Strings[Cnt]);
CloseFile(OFile);
Gruss

Tom

Hansa 19. Mai 2004 12:34

Re: Anzahl Zeilen in einem Textfile
 
Ah ja Gollums Beitrag habe ich nicht gesehen. 8) Ich habe einige größere Textdateien, die in eine Interbase Datenbank rein müssen. Da mir für so etwas nie eine Stringlist eingefallen wäre, habe ich deshalb mal eine kleine Testreihe gemacht, die ziemlich eindeutige Ergebnisse liefert:

1. Versuch : 400 MB, mein Vorschlag : 27 sek., mit der stringlist "out of memory"

2. Versuch : 120 MB, mein Vorschlag : 12 sek., mit der stringlist 334 sek. nur lesen, das free schätze ich zusätzlich noch auf 1-2 Min. Das ging nur einmal. Beim 2. Versuch blieb Rechner sogar hängen.

3. Versuch : 20 MB 570 ms, Stringliste 2994 ms

Insofern schätze/behaupte ich mal, über 2 MB ist die Stringliste "Firlefanz". :mrgreen:

[EDIT] Was natürlich auch heißt, daß sie für kleinere Sachen schon brauchbar ist. Der Performanceverlust und Speicherbedarf ist dann wohl kaum zu bemerken.

alcaeus 19. Mai 2004 12:38

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von TomDooley
Funktioniert, aber ist vielleicht nicht so sauber:

Du bist gut..nicht so sauber, also das ist noch sehr milde ausgedrückt. Ich versteh nicht was das ganze herumgeschreibe mit der Datei soll. Wieso verwendest du nicht eine Stringlist, fügst am Anfang deine ABC's ein, dann ganz vorne nochmal StringList1.Count und dann schreibst du das mit SaveToFile in die (inzwischen geschlossene) Datei?

sakura 19. Mai 2004 12:46

Re: Anzahl Zeilen in einem Textfile
 
Hier mal die Anzahl der Zeilen aus einer Datei in einer eigenen Funktion ;)

Delphi-Quellcode:
function CountLines(aFileName: string): Integer;
const
  BUF_SIZE = 4096;
var
  Buffer: array[0..Pred(BUF_SIZE)] of Byte;
  Cnt: Integer;
  FS: TFileStream;
begin
  FS := TFileStream.Create(aFileName, fmOpenRead or fmShareDenyWrite);
  try
    Result := 0;
    repeat
      Cnt := FS.Read(Buffer[0], BUF_SIZE);
      asm
        // load data count
        mov EAX, Cnt
        dec EAX
        js  @@NoData // no data

        // load current line count
        mov ECX, Result

        // loop data buffer
        @@LoopBuffer:
        // compare byte in memory
        cmp byte ptr[Buffer + EAX], $0A
        jnz @@CheckDataLeft // not a line break (#10)
        // increment line count
        inc ECX

        // goto next byte
        @@CheckDataLeft:
        dec EAX
        jns @@LoopBuffer

        // return result
        mov Result, ECX
        @@NoData:
      end;
    until Cnt < BUF_SIZE;
  finally
    FS.Free;
  end;
end;
Okay, ich gebe es, ich wollte mal wieder mit Assembler rumspielen :mrgreen:

...:cat:...

Hansa 19. Mai 2004 12:51

Re: Anzahl Zeilen in einem Textfile
 
Das da baue ich heut abend in meine Testreihe ein und versuche es mit den mageren 400 MB. :mrgreen:

sakura 19. Mai 2004 13:05

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von Hansa
Das da baue ich heut abend in meine Testreihe ein und versuche es mit den mageren 400 MB. :mrgreen:

Also für meine Datei 2domain.dat eine Liste von Domains->Firmennamen mit 1.611.355 Einträgen (56 MB) hat das Proggi zw. 256 Millisekunden und 820 Millisekunden benötigt ;)

...:cat:...

IngoD7 19. Mai 2004 13:39

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von Hansa
Beim 2. Versuch blieb Rechner sogar hängen.

Pah ... jetzt macht er schon seinen miesen Rechner für das Versagen meiner schönen TStringList verantwortlich! :x :mrgreen: :mrgreen:

Nein im Ernst, mir war eine "physikalische" Dateigrößengrenze, ab der TStringList "unwirtschaftlich" wird, nie bewusst. Ich denke jetzt aber auch, sie ist definitiv vorhanden. Nach den Zahlen und euren Schätzungen lege ich sie für mich bei 5-20 MB (je nach Anwendungsfall). Wenn eine Datei in einem Programm nur einmal durchgestöbert und zurückgeschrieben werden muss, ist es mir eigentlich egal, ob das eine halbe oder 3 sek dauert. Bis dahin ist TStringList vom Handling her unschlagbar. :stupid:

Hansa 19. Mai 2004 21:18

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von IngoD7
... für das Versagen meiner schönen TStringList verantwortlich! :x :mrgreen:

einmalig geht stringlist wohl sicher bis 50 MB. Oder eben nicht, wer weiß ? :mrgreen: Ich würde es nicht nutzen über max. 100-1000 Einträge.

Hansa 19. Mai 2004 21:24

Re: Anzahl Zeilen in einem Textfile
 
@Sakura: das ASM Programm braucht bei mir bei 480 MB 32-34 Sek. und stürzt manchmal ab. 8) Das readln Programm braucht 32-34 Sek. :mrgreen:

Kann dir die original-Datei gerne mal zuschicken. :shock:

sakura 20. Mai 2004 13:29

Re: Anzahl Zeilen in einem Textfile
 
Zitat:

Zitat von Hansa
Kann dir die original-Datei gerne mal zuschicken. :shock:

Keine Sorge, könnte ich mir selbst erstellen. Dazu zu sagen wäre wohl, daß der ASM-Code auf dem Delphi 7.1 Compiler basiert und daher nicht zwingend mit anderen korrekt läuft :mrgreen: (Das ist der Nachteil von Assembler in Delphi)

Aber ich habe zu Hause 120GB freien Speicherplatz, ich kann es ja mal testen :angle:

...:cat:...


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