![]() |
Zeilen in einer Datei zählen
Hallo,
gibt es eine einfache möglichkeit, rauszubekommen, wieviele zeilen eine datei hat? Es handelt sich dabei um recht kurze zeilen, aber bis ca 65000 stück. MFG Martin |
Re: Zeilen in einer Datei zählen
Hallo Martin,
am einfachsten dürfte es sein, die Datei in eine TStringList zu laden und deren Eigenschaft Count abzufragen. Gruß Hawkeye |
Re: Zeilen in einer Datei zählen
Oder so:
Delphi-Quellcode:
Var F: TextFile;
Count: Integer; Count := 0; AssignFile(F, ...); FileMode := fmOpenRead; Reset(F); While not EoF(F) do Begin ReadLn(F); Inc(Count); End; CloseFile(F); |
Re: Zeilen in einer Datei zählen
Noch eine Möglichkeit : Dateigröße durch Länge der Zeilen teilen. Geht allerdings nur richtig, sofern alle Zeilen gleich lang sind !
|
Re: Zeilen in einer Datei zählen
Vielen Dank für die Antworten.
zeilen sind nicht exakt gleich lang, können um 1-2 zeichen vareieren. ich hab mich jetzt für die TStringlist entschieden, hab aber noch 'ne frage, ob ich so speicher verliere:
Delphi-Quellcode:
die stinglist wird so ja 8 mal mit werten gefüllt. aber was passiert mit dem allokierten speicher der vorhergehenden einträge?
fileData := TStringList.Create;
for i := 1 to 8 do begin IF FileExists(filename[i]) then begin fileData.LoadFromFile(filename[i]); count[i]:=filedata.Count; end else count[i]:=0; end; filedata.Destroy; Gruß Martin |
Re: Zeilen in einer Datei zählen
Der Speicher sollte beim erneuten Füllen wieder freigegeben werden.
PS: Schon mal die Online-Hilfe zu ![]() Gruß Hawkeye |
Re: Zeilen in einer Datei zählen
Was ist mit himitsus Vorschlag ? Würde mich mal interessieren, was die Stringliste interessanter macht. Wenn die Zeilen nicht gleich lang sind, ist das der einfachste Vorschlag zum Ziel zu kommen. Und das ohne Create und Delete und Speicher. 8) Es gibt Error oder eben nicht, zumindest aber kein sich langsam aufbauendes Speicherleck.
|
Re: Zeilen in einer Datei zählen
Zitat:
|
Re: Zeilen in einer Datei zählen
Himitsu, was redest Du da ? Ich meine das :
Zitat:
|
Re: Zeilen in einer Datei zählen
Also, selbst wenn bei TextFile ein Fehler auftreten sollte dann ist wäre das Speicherleck jedenfalls geringer, als wenn was bei der StringList passiert (nach den obrigen Codes)
Aber man kann ja auch nochmehr an Code einsparren und die ganzen I/O-Checks weglassen
Delphi-Quellcode:
Var F: TextFile;
Count: Integer; Count := 0; AssignFile(F, ...); FileMode := fmOpenRead; {$I-} Reset(F); While not EoF(F) do Begin ReadLn(F); Inc(Count); End; CloseFile(F); {$I+} If IOResult <> 0 Then Count := -1; // Count >= 0 Count = Zeilenanzahl // Count = -1 Fehler Aber hast du dir mal angesehn, was TStringList.LoadFromFile macht? Das erstellt erstmal 'nen FileStream kopiert den Inhalt der Datei in einen String zerlegt den großen String in kleine Strings und fügt diese kleinen Strings in die StringListe ein ... und zwar jeden einzeln (was intern auch wieder einiges an rumcopieren verursacht) und gibt zum schluß wieder die beiden Strings und den FileStream frei (man hat also zeitweise über das Doppelte der Dateigröße im RAM und wenn die Datei aus nur einem String besteht sogar as Dreifache ... tja und zum Schluß muß auch alles wieder freigegeben werden |
Re: Zeilen in einer Datei zählen
Da stimme ich zu, was noch geht ist einen Grösseren Block zu lesen um die Geschwindigkeit zu erhöhen (Blockread).
|
Re: Zeilen in einer Datei zählen
Und hier mal eine kleine Anregung von mir *g*
Delphi-Quellcode:
function CountLines(const aFileName: string): Integer;
var DateiStream: TFileStream; CurrentByte: Word; Zeilen: Integer; const LineBreak = 10; begin result := -1; if (FileExists(aFileName)) then begin DateiStream := TFileStream.Create(aFileName, fmOpenRead); try zeilen := 0; if (DateiStream.Size > 0) then begin zeilen := 1; DateiStream.Position := 0; while DateiStream.Position < DateiStream.Size do begin DateiStream.Read(CurrentByte, 1); if (CurrentByte = LineBreak) then begin Inc(Zeilen); end; end; end; finally DateiStream.Free; end; result := Zeilen; end; end; procedure TDemoForm.btn_testClick(Sender: TObject); var Zeilen: Integer; begin Zeilen := CountLines('c:\test.txt'); ShowMessageFmt('%d', [Zeilen]); end; |
Re: Zeilen in einer Datei zählen
Hallo, da bin ich wieder.
Erst einmal auf die frage, warum ich mich für TStrinGrid entschieden hab. Hab den datentyp noch nicht benutzt und einfach mal ausprobieren wollen. Vielen Dank für den Hinweis mit .Destroy und .Free, hatte mir die hilfe nicht angeschaut und dacht mir .destroy könnt das tun, was ich will und das tat es dann auch (irgendwie ;-) ). Außerdem Es handelt sich nicht um große Dateien, sind kleiner als 1 MB, in sofern hab ich zeitlich keinen unterschied zu der methode von himitsu gesehen. Aber vielleicht ist es ein wenig mit Spatzen auf Kanonen schießen (oder so ähnlich ;-) ), um so ein kleine süße Integer zu bekommen. Nun bleibt nur noch die frage: TextFile oder FileStream, sprich Code von himitsu oder Sharky. Vielen dank erst einmal für eure ausführlichen Erläuterungen. Gruß Martin P.S. Kann mir vielleicht noch jeman sagen, wie man in einer Combobox es hinbekommt, dass man dort keine Eingaben tätigen kann, sondern nur aus den vorgegebenen werten wählen kann? Ich konnte die entsprechende Einstellung leider nicht finden. Eigentlich gehört das nicht zu diesem Topic, lohnt aber kaum, ein neues Topic aufzumachen, oder? |
Re: Zeilen in einer Datei zählen
Zitat:
Gruß Hawkeye |
Re: Zeilen in einer Datei zählen
ah, vielen dank. dann ist es nicht verwunderlich, dass ich es nicht gefunden hab, war primär auf der suche nach einem boolwert, den ich auf true oder false setzen muß...
|
Re: Zeilen in einer Datei zählen
Zitat:
Aber noch ein Effekt am Rande, weil die Geschwindigkeit erwähnt wurde. Mußte auch mal zigtausend Zeilen einlesen und in DB schreiben. Der Code sah ungefähr so aus :
Delphi-Quellcode:
Überlegung war folgende : was in die DB muß, das könnte man ja zumindest teilweise anzeigen, um zu sehen wie weit das Programm ist. Je nach Dateigröße lief das so ca. 5 Min. Was jetzt kommt ist kein Witz ! Das wollte keiner glauben, inkl. mir ! Das Programm lief plötzlich viel schneller. Allerhöchstens noch 2 Min. Gut, völlig unmöglich : DB gelöscht. Laufen lassen : die Daten waren da, wie vorher auch schon. Dateidatum von DB überprüft. Tja, die Zeit stimmte. Neuer DB-Cache irgendwie aktiviert, oder was gibts noch was es nicht geben sollte ?? Also Sicherung vom Vortag überspielt : 5 Min. Dann habe ich den Source verglichen. Zeile für Zeile, ob da event. eine größere Gruppe von DB-Feldern aus Versehen weg war. Nichts ! Bis auf diese Stelle war der Source identisch :
readln (t,st);
Memo1.Lines.Add (st); // in DB wegschreiben
Delphi-Quellcode:
Lediglich das Memo war auskommentiert, aber das war ja wohl ziemlich egal. Denkste ! Die Anzeige mit dem Memo war alleine für den Effekt verantwortlich ! Sonst nichts. :wall: Das ist auch eindeutig reproduzierbar. Ich glaube nicht, daß irgendwer zwischen readln oder Stream einen Effekt beobachtn kann, der nur irgendwie in die Nähe solcher Zeitunterschiede kommt.
readln (t,st);
//Memo1.Lines.Add (st); // in DB wegschreiben |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:21 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