Entwickler-Ecke

Dateizugriff - Ans Ende einer Datei schreiben?


Georg08 - Do 21.08.08 15:51
Titel: Ans Ende einer Datei schreiben?
wie kann ich unter delphi eine textdatei öffnen und ans ENDE der deatei, in einer NEUEN ZEILE etwas hinzufügen?


iKilledKenny - Do 21.08.08 15:54

Delphi Hilfe hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var

  f: TextFile;
begin
  if OpenDialog1.Execute then
  begin                    { open a text file }
    AssignFile(f, OpenDialog1.FileName);
    Append(f);
    Writeln(f, 'I am appending some stuff to the end of the file.'); 
    { insert code here that would require a Flush before closing the file }
    Flush(f);  { ensures that the text was actually written to file }
    CloseFile(f);
  end;

end;



Delete - Do 21.08.08 15:58

Guck dir mal die Methode Add von TStringList an:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.LoadFromFile(...);
    sl.Add('Meine neue Zeile am Ende der Datei');
    sl.SaveToFile(...);
  finally
    sl.Free;
  end;
end;


Georg08 - Do 21.08.08 15:58

geht es auch so:


Delphi-Quelltext
1:
2:
3:
assignfile(f, dateiname);
Writeln('Text am ende');
closefile(f);


Martin1966 - Do 21.08.08 16:00

user profile iconGeorg08 hat folgendes geschrieben:
geht es auch so:

hast du dir den Code von iKilledKenny oben angeschaut? Und was spricht dagegen es mal auszuprobieren? :gruelbe:


Georg08 - Do 21.08.08 16:02

die begriffe "Append" und "Flush" hab ich noch NIE gehört! deshalb meine frage, sonst würde ich den code sofort nehmen


iKilledKenny - Do 21.08.08 16:03

In diesem Falle wird mit F1 geholfen... 8)


Georg08 - Do 21.08.08 16:06

eigentlich schon, aber wenn ich unter F1 nichts finde frage ich hier ;)


Delete - Do 21.08.08 16:06

Bei iKilledKenny fehlt übrigens jedwede Fehlerbehandlung und gerade, wenn man die alten Pascal Routiunen zum Lesen und Schreiben von Dateien nimmt, sollte man eine Fehlerbehandlung einbauen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
var

  f: TextFile;
begin
  if OpenDialog1.Execute then
  begin                    { open a text file }
    AssignFile(f, OpenDialog1.FileName);
{$I-}
    Append(f);
{$I+}
    if IOResult = 0 then
    begin
      Writeln(f, 'I am appending some stuff to the end of the file.'); 
      { insert code here that would require a Flush before closing the file }
      Flush(f);  { ensures that the text was actually written to file }
      CloseFile(f);
    end
    else
      ShowMessage(SysErrorMessage(GetLastError));
  end;


iKilledKenny - Do 21.08.08 16:10

user profile iconLuckie hat folgendes geschrieben:
Bei iKilledKenny fehlt übrigens jedwede Fehlerbehandlung und gerade, wenn man die alten Pascal Routiunen zum Lesen und Schreiben von Dateien nimmt, sollte man eine Fehlerbehandlung einbauen.


Da hast du wohl recht, bei deiner Methode mit der StringList sehe ich aber auch keine. Desweiteren ist, wie auch meine Quote zeigte, der Code aus der Hilfe und es ging um die Frage, wie das funktioniert, nicht wie man IO-Fehler behandelt...


Delete - Do 21.08.08 16:16

Die StringList wirft eine Exception, die man im aufrufenden Code abfangen kann. Wie die alten Pascal Routinen reagieren, weiß ich leider nicht -- ichhabe es nie draufankommen lassen. ;)


BenBE - Do 21.08.08 16:18

@user profile iconLuckie: Ich dachte bis jetzt eigentlich immer, dass Du wüsstest, dass TStringList.LoadFromFile für große Dateien zu vermeiden ist.

Wenn schon, dann mit TFileStream.Position := TFileStream.Size gefolgt von nem TFileStream.CopyFrom aus dem TStringStream ;-)

@Pascal-Routinen: Die werfen bei {$I+} ne EIOException.


Martin1966 - Do 21.08.08 16:22

user profile iconBenBE hat folgendes geschrieben:
@user profile iconLuckie: Ich dachte bis jetzt eigentlich immer, dass Du wüsstest, dass TStringList.LoadFromFile für große Dateien zu vermeiden ist.

Zum einen: Wo steht denn etwas von einer "großen" Datei? Und zum anderen: Wieso sollte man generell sagen, dass man StringLists nicht für große Dateien verwenden sollte?

Lg, Martin


BenBE - Do 21.08.08 16:56

user profile iconMartin1966 hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
@user profile iconLuckie: Ich dachte bis jetzt eigentlich immer, dass Du wüsstest, dass TStringList.LoadFromFile für große Dateien zu vermeiden ist.

Zum einen: Wo steht denn etwas von einer "großen" Datei? Und zum anderen: Wieso sollte man generell sagen, dass man StringLists nicht für große Dateien verwenden sollte?

Lg, Martin

Wo stand denn, dass es sich NICHT um große Dateien handelt. ;-)

Warum ich den Einwand gebracht hab: Wenn es wirklich nur um das Anhängen einer einzigen Zeile geht, ist es meist wesentlich mehr Overhead die Datei VOLLSTÄNDIG in den Arbeitsspeicher zu laden (genau das war der Grund, für meinen Hinweis) und dann VOLLSTÄNDIG zurückzuschreiben. Mach das mal für 200 Zeilen und dein Programm ist Minutenlang beschäftigt nur immer wieder die gleichen Daten von der Platte zu kratzen.

Da vehält sich die obsolete Append-Methode bzw. meine Stream-Variante schon wesentlich performanter ;-)


Georg08 - Do 21.08.08 17:16

ähh.. also wenn ich das mal kurz unterbrechen darf:
mein problem ist NOCH NICHT GELÖST :D
die version von iKilledKenny:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
var  

 
  f: TextFile;  
begin  
  if OpenDialog1.Execute then  
  begin                    { open a text file }  
    AssignFile(f, OpenDialog1.FileName);  
    Append(f);  
    Writeln(f, 'I am appending some stuff to the end of the file.');   
    { insert code here that would require a Flush before closing the file }  
    Flush(f);  { ensures that the text was actually written to file }  
    CloseFile(f);  
  end;  

 
end;


hat nicht funktioniert außerdem benutze ich eine variable mit dateinamen was allerdings egal ist denke ich...

folgender ERROR wird ausgegeben:

Quelltext
1:
E/A-Fehler 32                    

dabei markiert delphi mir die zeile mit

Delphi-Quelltext
1:
Append(f);                    


Error 32 soll laut internet heißen, dass die datei schon offen ist, ich habe die datei zwar schon einmal geöffnet, aber unter einer anderen variable und ich habe sie geschlossen mit CloseFile()

WAS IST MEIN PROBLEM?


BenBE - Do 21.08.08 17:24

Zitat:
ERROR_SHARING_VIOLATION (32)
The process cannot access the file because it is being used by another process.


Heißt i.d.R. dass man noch einen anderen Prozess gestartet hat, der auf diese Datei zugreift. Schau also mal, ob du wirklich alle bisherigen Prozesse, die diese Datei benutzen bereits gekillt hast. Hier kann ggf. der ProzessExplorer von SysIntrnals, deren Handle.exe oder Tools wie der File Unlocker hilfreich sein ;-)


Georg08 - Do 21.08.08 17:37

ok ich bin jetzt endlich dahintergekommen:
ich idiot hab writeln(datnemae); gemacht ohne zu sagen, ih welche datei, da hat er natürlich gedacht, das datname die datei ist :oops: :autsch: :idea:

korrektur :
das problem mit append bleibt, ERROR 32??? was mach ich jetzt falsch?


Georg08 - Do 21.08.08 17:42


Delphi-Quelltext
1:
2:
3:
4:
5:
        CloseFile(lek);
      assignFile(f, dateiname);
      append(f);
      writeln(f, datname);
      CloseFile(f);



was is da falsch?


Georg08 - Do 21.08.08 17:53

noch was is komisch, nur bei append und rewrite bringt er den error reset kann ich machen?
weiß denn keiner was? :(


Carlo91 - Do 21.08.08 18:02

Hi,
der code funktioniert(ich benutze ihn auch):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure Log(sLogfile: String; sText: String);
var
  fLog: TextFile;
begin
  Assign(fLog, sLogfile);
  if (FileExists(sLogfile)) then Append(fLog) else Rewrite(fLog);
  WriteLn(fLog, sText);
  CloseFile(fLog);
end;


MfG Carlo


jaenicke - Do 21.08.08 18:37

user profile iconGeorg08 hat folgendes geschrieben:
noch was is komisch, nur bei append und rewrite bringt er den error reset kann ich machen?
weiß denn keiner was? :(
Append und Rewrite öffnen die Datei zum Schreiben, Reset nur zum Lesen, und Lesen kann man durchaus ja auch mehrfach, d.h. wenn 5 Programme gleichzeitig die Datei lesen stört das ja nicht.

Beim gleichzeitigen Schreiben würde es aber Probleme geben, daher der Fehler.

Du kannst dein Programm anhängen, denn der Fehler muss ja im restlichen Quelltext irgendwo stecken, du kannst auch mit dem bereits erwähnten ProcessExplorer herausfinden, ob es tatsächlich dein Programm ist, das den Zugriff sperrt. (Menü Find, dann nach dem Dateinamen suchen)


Delete - Fr 22.08.08 09:17

user profile iconBenBE hat folgendes geschrieben:
@user profile iconLuckie: Ich dachte bis jetzt eigentlich immer, dass Du wüsstest, dass TStringList.LoadFromFile für große Dateien zu vermeiden ist.

Da stand nichts von von der Größe Dateien, also warum nicht TStringList vorschlagen, das sollte für einen Anfänger die einfachste Möglichkeit sein eine Zeile an eine Textdatei zu hängen.

Und davon dass das ganze ein paar tausendmal in einer Schleife passieren soll war auch nicht die Rede.

Woher habt ihr eure Informationen?