Append bei Textdatei bringt error

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Benutzeravatar
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

Beitrag von Winni »

Hi!

Nochmals:

Win7/64 meldet immer eine Dateigröße von Null bevor die Datei geschlossen wird.

Win10 ist in der Firma verboten, was bei dieser Datenkrake auch gut ist.
Privat hol ich mir das schon mal garnicht ins Haus.

Gibt ja Linux on the Desktop. Seit über 25 Jahen.
Und ext2 war damals die Spitze der "kleinen" Dateisysteme.
NTFS schlüpte gerade mit Windows NT aus dem Ei. Das wurde aber von nur von Tech-Freaks benutzt.

Winni

kirchfritz
Beiträge: 169
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: Append bei Textdatei bringt error

Beitrag von kirchfritz »

Wie sieht denn jetzt die Lösung der Ausgangsfrage aus?

Socke
Lazarusforum e. V.
Beiträge: 3158
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

Beitrag von Socke »

kirchfritz hat geschrieben:
Fr 3. Sep 2021, 00:59
Wie sieht denn jetzt die Lösung der Ausgangsfrage aus?
Es ist das zu validieren (FileExists), was man hinterher öffnen möchte. Siehe viewtopic.php?p=123535#p123535.
Ich empfehle immer, die Datei direkt zu öffenen. Wenn sie nicht da ist, kann man die Exception abfangen und darauf reagieren. Andere sehen das anders.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
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

Beitrag von Winni »

kirchfritz hat geschrieben:
Fr 3. Sep 2021, 00:59
Wie sieht denn jetzt die Lösung der Ausgangsfrage aus?
Hi

Lesen hilft.Dieser Thread, Seite 2, Beitrag 2.

Winni

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Append bei Textdatei bringt error

Beitrag von wp_xyz »

Winni hat geschrieben:
Fr 3. Sep 2021, 18:11
kirchfritz hat geschrieben:
Fr 3. Sep 2021, 00:59
Wie sieht denn jetzt die Lösung der Ausgangsfrage aus?
Hi

Lesen hilft.Dieser Thread, Seite 2, Beitrag 2.

Winni
Oder schon früher: Seite 1, Beitrag 2. Im Beitrag 4 bestätigt der Thread-Starter, dass damit das Problem gelöst ist.

kirchfritz
Beiträge: 169
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: Append bei Textdatei bringt error

Beitrag von kirchfritz »

Sorry für meine scheinbar dumme Frage nach einer Lösung, aber ich habe tatsächlich ein Problem mit Append bei Textdateien:

Zur Veranschaulichg habe ich ein kleines Windows-Kommandozeilenprogramm geschrieben.

Code: Alles auswählen

program WriteLog(input, output, stdErr);
uses  Sysutils;
const C_FNAME = 'textfile.txt';
var tfOut: TextFile;
procedure Log(aMessage : String);
var ior : Integer;
begin
  AssignFile(tfOut, C_FNAME);
  try
    {$I-}
      reset(tfOut);
    {$I+}
    ior := IOResult;
    if ior <> 0 then
    begin
      writeln('IOResult=',ior);
      rewrite(tfOut);  // File not found
    end;
    append(tfOut);
    writeln(tfOut, DateTimeToStr(Now)+' '+aMessage);
    Flush(tfOut);
    CloseFile(tfOut);
  except
    on E: EInOutError do
     writeln('File handling error occurred. Details: ', E.Message);
  end;
end;
procedure Run;
var i : integer;
    s : String;
begin
  randomize;
  s := IntToStr(random(10000));
  writeln('ID:'+s);
  for i := 1 to 10000 do
    Log('ID: '+s+' '+IntToStr(i)+'. Testnachricht');
end;
begin
  Run;
  writeln('Fertig!');
  readln;
end.         
Dieses Programm versucht in einer Schleife 10000 mal einen String in eine Log-Datei zu schreiben.
Verwendet wird AssignFile(f)+AppendFile+Write(f,'MessageText')+Closefile(f) siehe Quellcode im Anhang.
Dies klappt alles hervorragend. Alle 10000 LogEinträge finden sich in der Log-Datei wieder.
Das Problem: Starte ich das Programm mehrmals, (siehe BatchDatei auch im Anhang),

Code: Alles auswählen

REM
del *.txt
start writelog
start writelog
start writelog
pause
laufen also mehrere Instanzen meines Programms, die alle in die gleiche Log-Datei schreiben wollen, bremsen sich die gleichzeitigen Programme gegenseitig aus, und ich erhalte "Access Denied" Fehlermeldungen.


Gibt es denn dafür Lösungsvorschläge Eurerseits?
Ich bin mit meinen Pascal-Kenntnissen am Ende.

Viele Grüße
Fritz
Dateianhänge
ScreenShot der Fehlermeldungen
ScreenShot der Fehlermeldungen
ScreenShot_Errors.png (84.99 KiB) 2383 mal betrachtet
WriteLog.zip
Quellcode + Batchdatei
(2.34 KiB) 99-mal heruntergeladen

Benutzeravatar
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

Beitrag von Winni »

Hallo!

Etwas Grundwissen:

In den herkömmlichen Dateisystemen sind Dateien monogam:

Wenn Du mir reset oder rewrite eine Datei öffnest, dann gehört die Datei zu dem Programm, das sie geöffnet hat. Bis Du dich mit einem closefile scheiden lässt. Andere Programme, die mit der Datei anbändeln möchten, werden zurückgewiesen - wie Du erlebt hast.

Die Lösungen:
Jeder Instanz des Programms hat seine eigene Datei. Die Dateinamen kann man per Zufallsgenerator mit großen Zahlen erzeugen - zur Vermeidung von Kollisionen. Oder man nennt sie log1, Wenn log1 vorhanden ist nennt man sie log2. ..... Wenn man unter Linux ist kann man auch den pid nehmen - der ist eindeutig. Falls man die 3 Dateien hinterher mergen muss, kann man jede Zeile mit einem Timestamp am Anfang versehen.Kann man besser sortieren. Für den Timestamp entweder ISO-Format oder Unix-time zum einfachen Sortieren nehmen.

-----

Wenn Du aber alles in einer Datei haben möchtest:
Nach dem Schreiben von Daten die Datei schliessen.
Wenn wieder Daten vorliegen:

repeat
Versuchen die Datei zu öffnen.
--> ioResult > 0 --> sleep (50)
until ioResult = 0
Daten schreiben
Datei schließen

Das ist aber nix für Echtzeit-Anwendungen

Oder Du nimmst ein Datenbänkchen.
Dafür sind sie da.

Winni

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 988
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Linux Mint 20 , FPC 3.3.1 , Lazarus 2.1.0 -Win10 & XE7Pro
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Append bei Textdatei bringt error

Beitrag von kralle »

Moin,
kirchfritz hat geschrieben:
Mo 6. Sep 2021, 09:22
laufen also mehrere Instanzen meines Programms, die alle in die gleiche Log-Datei schreiben wollen, bremsen sich die gleichzeitigen Programme gegenseitig aus, und ich erhalte "Access Denied" Fehlermeldungen.

Gibt es denn dafür Lösungsvorschläge Eurerseits?
Also, ich würde die Datei die aktuell schreiben will, einen "lock.txt" schreiben lassen.
Wenn schon einen "lock.txt" schon vorhanden ist, kann keine Datei geschrieben werden.

Also, schauen ob die Datei vorhanden ist,.
Wenn ja, warten bis die Datei nicht vorhanden ist - dann deine Daten schreiben.
Wenn nein, "lock.txt" schreiben - Deine Daten schreiben - "lock.txt" löschen.

Nur so eine Idee ...

Gruß Heiko
OS: Manjaro Linux, Debian und Windows 10
FPC-Version: 3.2.2 , Lazarus 3.0
+ Delphi XE7SP1

kirchfritz
Beiträge: 169
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: Append bei Textdatei bringt error

Beitrag von kirchfritz »

Hallo Heiko,

habe versucht Deine Idee umzusetzen, hat auch nichts geholfen:

Code: Alles auswählen

program WriteLog;
uses  Sysutils;
const C_FNAME = 'textfile.txt';
var tfOut: TextFile;
procedure Log(aMessage : String);
var ior : Integer;
begin
  if fileexists('lock.txt') then
  repeat
    writeln(aMessage);
  until not fileExists('lock.txt');
  repeat
    AssignFile(tfOut, 'lock.txt');
    Rewrite(tfOut);
    writeln(tfOut,'1');
    Flush(tfOut);
    CloseFile(tfOut);
  until fileExists('lock.txt');
  AssignFile(tfOut, C_FNAME);
  try
    {$I-}
      reset(tfOut);
    {$I+}
    ior := IOResult;
    if ior <> 0 then
    begin
      writeln('IOResult=',ior);
      rewrite(tfOut);  // File not found
    end;
    append(tfOut);
    writeln(tfOut, DateTimeToStr(Now)+' '+aMessage);
    Flush(tfOut);
    CloseFile(tfOut);
    DeleteFile('lock.txt');
  except
    on E: EInOutError do
    begin
      writeln('File handling error occurred. Details: ', E.Message);
      DeleteFile('lock.txt');
    end;
  end;
end;
procedure Run;
var i : integer;
    s : String;
begin
  randomize;
  s := IntToStr(random(10000));
  writeln('ID:'+s);
  for i := 1 to 10000 do
    Log('ID: '+s+' '+IntToStr(i)+'. Testnachricht');
end;
begin
  Run;
  writeln('Fertig!');
end.


Benutzeravatar
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

Beitrag von Winni »

Hi!

Wenn Du den Lockfile setzt, aber nie wieder frei gibst, dann kann das auch nix werden.
Dein Lockfile existiert bis an das Ende aller Tage.

Winni

kirchfritz
Beiträge: 169
Registriert: Mo 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 3.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Nürnberg

Re: Append bei Textdatei bringt error

Beitrag von kirchfritz »

Hallo Winni,
dass ich an zwei Stellen mit

Code: Alles auswählen

DeleteFile('lock.txt')
die lock.txt Datei lösche, ist Dir irgendwie entgangen, oder?
Muss man zusätzlich zum

Code: Alles auswählen

deleteFile('lock.txt')
die gelöschte Datei auch noch freigeben?
Davon habe ich noch nie gehört.

Antworten