![]() |
Daten schrittweise in Textdatei speichern
Hallo,
ich frage mich gerade wie ich Daten schrittweise in eine Textdatei speichern kann. Ich habe vor mir einen eigenen Logger zu programmieren, der mir in meinen Programmen Ereignisse und so weiter aufzeichnet und diese dann speichert. Nun will ich gerne die Speicherung intern über eine Stringliste vornehmen. Da diese aber immer größer wird will ich diese nach Erreichen einer bestimmten Größe automatisch in eine Textdatei abspeichern, und die interen Liste leeren. Wie kann man jetzt neue Daten wieder an die Textdatei, also ans Ende anhängen, ohne diese wieder z.b. zuerst in eine Stringliste zu laden? Für Hilfe bin ich dankbar! LG Marco |
AW: Daten schrittweise in Textdatei speichern
|
AW: Daten schrittweise in Textdatei speichern
- FileStream öffnen (wenn Datei nicht existiert, dann eine erstellen)
- Position ans Ende - StringListe in diesen Stream kopieren (also anhängen) - StringListe leeren oder die besagten (alten) Textprozeduren (ala AssignFile und WriteLn) oder ![]() ![]() |
AW: Daten schrittweise in Textdatei speichern
Darf ich fragen, warum Du die Log-Messages in eine StringList speichern willst und erst in einem zweiten Schritt in eine Datei? Direkt in die Datei wäre deutlich einfacher (siehe:
![]() |
AW: Daten schrittweise in Textdatei speichern
@himi: ja stimmt, diese konvertiererei dieser Urzeitunits macht mich total Kirre... :wall:
Aber ich hab hier noch eine andere Variante, die dich bestimmt interessiert :stupid:
Delphi-Quellcode:
function SetFilePointer(hFile: Cardinal; lDistanceToMove: Longint; lpDistanceToMoveHigh: Pointer;
dwMoveMethod: Cardinal): Cardinal; stdcall; external kernel32 name 'SetFilePointer'; function FileExists(const FileName: string; const PFileSize: PInt64 = nil): Boolean; {$IFDEF Inln}inline;{$ENDIF} var myFile: Cardinal; myFindData: TWin32FindData; TheInt64: Int64; begin myFile := FindFirstFile(@FileName[1], myFindData); Result := myFile <> INVALID_HANDLE_VALUE; if Result then begin FindClose(myFile); if PFileSize <> nil then begin TheInt64 := PFileSize^; Int64Rec(TheInt64).Lo := myFindData.nFileSizeLow; Int64Rec(TheInt64).Hi := myFindData.nFileSizeHigh; PFileSize^ := TheInt64; end; end; end; function OpenFile(const FileName: string; var hFile: Cardinal; const PFileSize: PInt64 = nil): Boolean; {$IFDEF Inln}inline;{$ENDIF} begin Result := FileExists(FileName, PFileSize); if Result then begin hFile := CreateFile(@FileName[1], GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); Result := hFile <> INVALID_HANDLE_VALUE; end; end; function WriteFileStr(const hFile: Cardinal; const AStr: string): Boolean; {$IFDEF Inln}inline;{$ENDIF} var Size, BytesWritten: Cardinal; begin Size := Length(AStr)*SizeOf(Char); Result := (WriteFile(hFile, AStr[1], Size, BytesWritten, nil)) and (Size = BytesWritten); end; function AddTextToFile(const Text, FilePath: string): Boolean; {$IFDEF Inln}inline;{$ENDIF} var hFile: Cardinal; fs: UInt64; begin Result := false; if not OpenFile(FilePath, hFile, @fs) then Exit; if SetFilePointer(hFile, fs+Length(Text)*SizeOf(Char), nil, FILE_BEGIN) = fs+Length(Text)*SizeOf(Char) then begin SetEndOfFile(hFile); Result := (SetFilePointer(hFile, fs, nil, FILE_BEGIN)=fs) and WriteFileStr(hFile, Text); end; CloseHandle(hFile); end; |
AW: Daten schrittweise in Textdatei speichern
Zitat:
Ich kann nur empfehlen, diese Inline-Klauseln komplett wegzulassen! Wenn man ausserdem noch bedenkt, dass der Zugriff auf Dateien Milliardenfach mehr Zeit benötigt als mit einer Inline-Funktion gespart werden könnte.... |
AW: Daten schrittweise in Textdatei speichern
Und solange die Log-Datei kleiner als 2 GB bleibt und man kein Unicode benötigt, funktionieren die alten Pascal-Datei-Funktionen auch noch ganz gut.
|
AW: Daten schrittweise in Textdatei speichern
@shmia:
Dafür gibts ja den Direktivenschalter. Aber welchen Nachteil bekommt Entwickler und Anwender (außer der größeren Exe) doch gleich? |
AW: Daten schrittweise in Textdatei speichern
Hallo,
ich verwende üblicherweise die folgende Procedure in einer separaten Unit:
Delphi-Quellcode:
Dort, wo ich etwas protokollieren will, reicht dann ein einfaches
procedure WriteLog(strText: string);
var tfLog: TextFile; strLogPath: string; strLogFile: string; begin strLogPath := GetSpecialFolderLocation($23) + 'meinprogramm\Logs'; if not DirectoryExists(strLogPath) then ForceDirectories(strLogPath); strLogFile := strLogPath + '\LOG-' + FormatDateTime('YYYY-MM-DD', Now()) + '.TXT'; AssignFile(tfLog, strLogFile); if FileExists(strLogFile) then Reset(tfLog) else Rewrite(tfLog); Append(tfLog); WriteLn(tfLog, FormatDateTime('HH:MM:SS', Now()) + ' - ' + strText); CloseFile(tfLog); end;
Delphi-Quellcode:
, um einen Protokolleintrag inklusive aktueller Zeit zu erstellen.
WriteLog('Das ist wichtig');
Man könnte das ganze noch in ein try..except oder try...finally packen, hat aber bisher ganz gut funktioniert. Gruß Frank |
AW: Daten schrittweise in Textdatei speichern
Zitat:
Zusätzlich verwirren sie den Entwickler mit visuellem Störfeuer. Je mehr Code ein Entwickler lesen muss, umso schlechter wird seine Leistung beim Verstehen von Sourcecode. Siehe auch: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:24 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