Append bei Textdatei bringt error
- Jim Knopf
- Beiträge: 98
- Registriert: So 18. Mai 2014, 15:16
- OS, Lazarus, FPC: Win10
- CPU-Target: 64Bit
- Wohnort: Klagenfurt
- Kontaktdaten:
Re: Append bei Textdatei bringt error
Ist das eine Multiuseranwendung?
Wenn nein, wäre dann nicht eine simple TStringList viel einfacher?
Wenn nein, wäre dann nicht eine simple TStringList viel einfacher?
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Hallo Bergmensch1
Ich hab Deinen Code mal grundlegend aufgeräumt.
Fangn wir mit den Fehlern an.
Falsch und gefährlich:
Niemals die Variable Form1 in der Klassendefinition von TForm1 aufrufen.
Weil:
Nun gibt es irgenwo eine zweite Form namens KarlHeinz als Instanzvon TForm1. Möglicherweise in einer ganz anderen Unit.
Und dort ist Form1 evtl. undefiniert. Und nun? So etwas ist erstens falsch und führt zweiten zu schwer lokalisierbaren Fehlern.
Immer so
Die Timer: Du benötigst den einen Timer nur, um den anderen zu starten.
Das liegt nun in Formcreate.
Die ganze Arie mit Datei, Pfad und fileExists wird so gekürzt:
Paramstr(0) war gestern. Den absoluten Pfad der exe-Datei erhält man mit Application.Location
Es verkürzt sich auft
Der Pfad entfällt.
Den Test auf die Existenz der Datei muss man auch nur am Anfang machen, weil Deine Anwendung offensichtlich single user ist, also Dir niemand im Betrieb die Datei löscht.
Also tested Formcreate die Existenz und erzeugt im Zweifelsfall eine neue Datei.
Dann muss nie wieder getested werden.
Project anbei.
Grüße
Winni
Ich hab Deinen Code mal grundlegend aufgeräumt.
Fangn wir mit den Fehlern an.
Falsch und gefährlich:
Code: Alles auswählen
Procedure TForm1.xyz;
begin
Form1.Komponente .....;
end;
Weil:
Nun gibt es irgenwo eine zweite Form namens KarlHeinz als Instanzvon TForm1. Möglicherweise in einer ganz anderen Unit.
Und dort ist Form1 evtl. undefiniert. Und nun? So etwas ist erstens falsch und führt zweiten zu schwer lokalisierbaren Fehlern.
Immer so
Code: Alles auswählen
Procedure TForm1.xyz;
begin
Komponente .....;
end;
Das liegt nun in Formcreate.
Die ganze Arie mit Datei, Pfad und fileExists wird so gekürzt:
Paramstr(0) war gestern. Den absoluten Pfad der exe-Datei erhält man mit Application.Location
Es verkürzt sich auft
Code: Alles auswählen
Dateiname := Application.Location+'Test.txt';
Den Test auf die Existenz der Datei muss man auch nur am Anfang machen, weil Deine Anwendung offensichtlich single user ist, also Dir niemand im Betrieb die Datei löscht.
Also tested Formcreate die Existenz und erzeugt im Zweifelsfall eine neue Datei.
Dann muss nie wieder getested werden.
Project anbei.
Grüße
Winni
- Dateianhänge
-
Messwerte.zip
- (127.14 KiB) 124-mal heruntergeladen
-
- Beiträge: 958
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Append bei Textdatei bringt error
Man sollte bei sowas wie Append (oder auch Rewrite bzw. Reset) immer auf Fehler abprüfen, da zum Beispiel keine passenden Berechtigungen existieren könnten (was FileExists ja nicht überprüft) oder zufällig der Scheduler des Betriebssystem deinen Thread zwischen FileExists und Append schlafen gelegt und ein anderer Thread (eventuell auch einer anderen Anwendung) in der Zwischenzeit diese Datei angelegt hat (das ist natürlich bei manchen Dateien wahrscheinlicher als bei anderen, aber man sollte diesen Fall nicht unterschätzen).Winni hat geschrieben: Fr 20. Aug 2021, 20:32 Nach dem FileExists solltest Du eigentlich kein try mehr benötigen - es sei denn, die Festplatte ist defekt.
Falsch. Die AssignFile-overloads sind in der Unit ObjPas deklariert, welche automatisch bei Verwendung von Modi wie ObjFPC oder Delphi verwendet wird.
FPC Compiler Entwickler
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Na, das ist aber arg konstruiert. Ist mir in über 40 Jahren Pascal nicht ein einzige Mal passiert.PascalDragon hat geschrieben: Do 26. Aug 2021, 16:09
Man sollte bei sowas wie Append (oder auch Rewrite bzw. Reset) immer auf Fehler abprüfen, da zum Beispiel keine passenden Berechtigungen existieren könnten (was FileExists ja nicht überprüft) oder zufällig der Scheduler des Betriebssystem deinen Thread zwischen FileExists und Append schlafen gelegt und ein anderer Thread (eventuell auch einer anderen Anwendung) in der Zwischenzeit diese Datei angelegt hat (das ist natürlich bei manchen Dateien wahrscheinlicher als bei anderen, aber man sollte diesen Fall nicht unterschätzen).
Winni
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Append bei Textdatei bringt error
Sobald du mit anderen Programmen über Dateien interagieren möchtest, ist das tatsächlich ganz normal.Winni hat geschrieben: Do 26. Aug 2021, 19:12 Na, das ist aber arg konstruiert. Ist mir in über 40 Jahren Pascal nicht ein einzige Mal passiert.
Solltest du in deinem Programm nur spezifische Dateien bearbeiten, kommt das in der Tat eher selten vor.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Hi!Socke hat geschrieben: Do 26. Aug 2021, 21:32 Sobald du mit anderen Programmen über Dateien interagieren möchtest, ist das tatsächlich ganz normal.
Solltest du in deinem Programm nur spezifische Dateien bearbeiten, kommt das in der Tat eher selten vor.
Programm A schreibt in Datei X.
Programm B liest Datei X
Programm B schreibt in Datei Y
Programm A liest Datei Y
Brauchst Du nicht mal Semaphore oder sonstwas.
Brauchst auch kein fileExists.
Musst Du nur pollen ob die Dateigröße sich verändert hat.
Geht astrein mit Linux-Dateisystem.
Gibt aber Probleme in Windows.
Winni
-
- Beiträge: 958
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Append bei Textdatei bringt error
Da ist nichts dran konstruiert, das basiert auf Fällen, die mir so bereits passiert sind und das unabhängig von Pascal (da dies kein Problem der Sprache ist).Winni hat geschrieben: Do 26. Aug 2021, 19:12Na, das ist aber arg konstruiert. Ist mir in über 40 Jahren Pascal nicht ein einzige Mal passiert.PascalDragon hat geschrieben: Do 26. Aug 2021, 16:09
Man sollte bei sowas wie Append (oder auch Rewrite bzw. Reset) immer auf Fehler abprüfen, da zum Beispiel keine passenden Berechtigungen existieren könnten (was FileExists ja nicht überprüft) oder zufällig der Scheduler des Betriebssystem deinen Thread zwischen FileExists und Append schlafen gelegt und ein anderer Thread (eventuell auch einer anderen Anwendung) in der Zwischenzeit diese Datei angelegt hat (das ist natürlich bei manchen Dateien wahrscheinlicher als bei anderen, aber man sollte diesen Fall nicht unterschätzen).
Aber das ist ein anderer Usecase alsWinni hat geschrieben: Do 26. Aug 2021, 23:21Hi!Socke hat geschrieben: Do 26. Aug 2021, 21:32 Sobald du mit anderen Programmen über Dateien interagieren möchtest, ist das tatsächlich ganz normal.
Solltest du in deinem Programm nur spezifische Dateien bearbeiten, kommt das in der Tat eher selten vor.
Programm A schreibt in Datei X.
Programm B liest Datei X
Programm B schreibt in Datei Y
Programm A liest Datei Y
Brauchst Du nicht mal Semaphore oder sonstwas.
Brauchst auch kein fileExists.
Musst Du nur pollen ob die Dateigröße sich verändert hat.
Programm A prüft, ob Datei X bereits existiert
Programm A legt Datei X an, falls nicht
Programm B prüft, ob Datei X bereits existiert
Programm B legt Datei X an, falls nicht
Da kann nämlich je nach Scheduling auch das folgende bei rauskommen:
Programm A prüft, ob Datei X bereits existiert
Programm B prüft, ob Datei X bereits existiert
Programm B legt Datei X an, falls nicht
Programm A legt Datei X an, falls nicht (und hier knallt's dann)
Das hat nichts mit Dateisystem zu tun (ein Ext3 unter Windows würde sich genauso wie ein NTFS unter Windows verhalten, genauso wie sich ein NTFS unter Linux genauso wie ein Ext3 verhält), sondern damit, dass Linux "Advisory File Locking" und Windows "Mandatory File Locking" verwendet und sich mit letzterem exklusiver Zugriff auch tatsächlich durchsetzen lässt.Winni hat geschrieben: Do 26. Aug 2021, 23:21 Geht astrein mit Linux-Dateisystem.
Gibt aber Probleme in Windows.
FPC Compiler Entwickler
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Hi!
Natürlich hat das was mit dem Dateisystem zu tun.
NTFS schreibt die Dateigröße erst nach einem close(file) auf die Platte.
ext2/3/4 schreibt bei jedem Schreibzugriff die aktuelle Größe auf die Platte.
Winni
Natürlich hat das was mit dem Dateisystem zu tun.
NTFS schreibt die Dateigröße erst nach einem close(file) auf die Platte.
ext2/3/4 schreibt bei jedem Schreibzugriff die aktuelle Größe auf die Platte.
Winni
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Append bei Textdatei bringt error
Wobei die Dateigröße in PascalDragons Beispiel vollkommen egal ist. Da hat nur ein CreateFile Aufruf aber noch kein Write-Aufruf stattgefunden.Winni hat geschrieben: Fr 27. Aug 2021, 13:21 Natürlich hat das was mit dem Dateisystem zu tun.
NTFS schreibt die Dateigröße erst nach einem close(file) auf die Platte.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Socke hat geschrieben: Fr 27. Aug 2021, 14:44Wobei die Dateigröße in PascalDragons Beispiel vollkommen egal ist. Da hat nur ein CreateFile Aufruf aber noch kein Write-Aufruf stattgefunden.Winni hat geschrieben: Fr 27. Aug 2021, 13:21 Natürlich hat das was mit dem Dateisystem zu tun.
NTFS schreibt die Dateigröße erst nach einem close(file) auf die Platte.
Ich hab mich natürlich auf mein Beispiel bezogen.
Da spielt das sehr wohl eine Rolle.
Winni
-
- Beiträge: 958
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Append bei Textdatei bringt error
Nein, das hat nichts mit dem Dateisystem zu tun. Es hat damit zu tun, wie das Betriebssystem mit dem Dateisystem arbeitet. Und das hängt komplett von der Kombination aus Betriebssystem und Dateisystem ab. Und wenn deine Aussage bzgl. NTFS stimmen würde, dann könnte man offen gehaltenen Dateien auf einem NTFS unter Windows nicht beim wachsen zusehen, was man nämlich kann.Winni hat geschrieben: Fr 27. Aug 2021, 13:21 Natürlich hat das was mit dem Dateisystem zu tun.
NTFS schreibt die Dateigröße erst nach einem close(file) auf die Platte.
ext2/3/4 schreibt bei jedem Schreibzugriff die aktuelle Größe auf die Platte.
FPC Compiler Entwickler
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Stimmt nicht unter Win7/64. Dateigröße bleibt Null bis zum close(file).PascalDragon hat geschrieben: Sa 28. Aug 2021, 12:01 [Und wenn deine Aussage bzgl. NTFS stimmen würde, dann könnte man offen gehaltenen Dateien auf einem NTFS unter Windows nicht beim wachsen zusehen, was man nämlich kann.
Winni
- kralle
- Lazarusforum e. V.
- Beiträge: 1200
- Registriert: Mi 17. Mär 2010, 14:50
- OS, Lazarus, FPC: Manjaro Linux, Mint und Windows 10 ,Lazarus 3.99, FPC-Version: 3.3.1
- CPU-Target: 64Bit
- Wohnort: Bremerhaven
- Kontaktdaten:
Re: Append bei Textdatei bringt error
Ihr driftet ab und werdet rauer im Ton.
Bitte nicht ...
Gruß Heiko
Bitte nicht ...
Gruß Heiko
OS: MX Linux, Linux Mint und Windows 10
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1
FPC-Version: 3.3.1 , Lazarus 3.99
+ Delphi XE7SP1
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Append bei Textdatei bringt error
Hi!
????
Wir werden nicht rauer.
Und über die rauen Fakten: Beschwer dich bei NTFS.
Winni
????
Wir werden nicht rauer.
Und über die rauen Fakten: Beschwer dich bei NTFS.
Winni
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Append bei Textdatei bringt error
Was auch nicht ganz richtig ist. Die Dateigröße wird mit jeder Änderung aktualisiert. Der Verzeichniseintrag wird aber nur bei einem Close aktualisiert.Winni hat geschrieben: Sa 28. Aug 2021, 13:04 Stimmt nicht unter Win7/64. Dateigröße bleibt Null bis zum close(file).
Sehr schön beschrieben ist dies im Blog
Code: Alles auswählen
Why is the file size reported incorrectly for files that are still being written to?
Ein Detail aus dem Blog von 2011 stimmt nicht mehr ganz für Windows 10. Der Explorer kann durchaus die tatsächliche Dateigröße aktualisieren, wenn man auf "Aktualisieren" klick. Dazu scheint er wohl wie im Blogbeitrag beschrieben die Datei zu öffnen und zu schließen, da sich dies auch auf ein FindFirst() im laufenden Programm auswirkt. Ein automatisches Update erhält er tatsächlich erst mit dem Schließen der Datei.
Mit einem kleinen Programm kann man das ganz einfach untersuchen.
Code: Alles auswählen
program project1;
{$Mode objfpc}{$H+}
uses
Windows, sysutils, classes;
// Die Testdatei
const
FILENAME = 'myfile';
// ermittelt die Dateigröße per FindFirst
function GetEnumeratedSize: Qword;
var
srcrec: TRawByteSearchRec;
begin
if FindFirst(FILENAME, faAnyFile, srcrec) = 0 then
begin
Result := srcrec.Size;
FindClose(srcrec);
end;
end;
var
f: TFileStream;
Buffer: Array[0..999] of Byte; // ein Puffer, der in die Datei geschrieben wird
c: String = #0;
fsize: Int64Rec;
begin
WriteLn('Enumerated Size: ', GetEnumeratedSize);
f := TFileStream.Create(FILENAME, fmCreate);
try
repeat
case c of
#10, #13: continue;
'c', 'C': begin
f.Write(Buffer[0], Length(Buffer));
WriteLn('Stream Size: ', f.Size);
fsize.Lo := GetFileSize(f.Handle, @fsize.Hi);
WriteLn('Windows File Size: ', Int64(fsize));
WriteLn('Enumerated Size: ', GetEnumeratedSize);
end;
end;
ReadLn(c);
until c[1] in ['x', 'X'];
finally
FreeAndNil(f);
end;
WriteLn('Enumerated Size: ', GetEnumeratedSize);
ReadLn;
end.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein