Entwickler-Ecke
Dateizugriff - Warum sind Delphi-Textdateien schreibgeschützt?
ueberschecker - Mo 30.08.04 19:39
Titel: Warum sind Delphi-Textdateien schreibgeschützt?
Hallo,
ich schreibe gerade in Delphi7 ein eigentlich ziemlich simples Programm, was mit Textdateien arbeitet. Da ich vorher eigentlich nur in C++ programmiert habe, weiß ich nicht, warum Delphi alle Textdateien, die mit Reset() bzw. Rewrite() geöffnet wurden schreibgeschütz öffnet. So steht es zumindestens in der Hilfe. Das Programm steigt mit E/A-Fehler 105 aus. Was soviel heißt wie Datei wurde nicht zum Schreibem geöffnet. Wenn ich die Datei mit Append() öffne klappt alles ohne Probleme, aber ich möchte ja auch in der Datei was verändern. Wie kann ich den Schreibschutz entfernen? "fileMode:=fmOpenReadWrite" funktioniert nicht.
MfG
Delete - Mo 30.08.04 19:48
Schon mal unter AssignFiel in der Hilfe nachgekuckt?
ueberschecker - Mo 30.08.04 21:20
Also bei mir steht da nichts zum Problem. (Delphi 7 Personal) ich habe jedesmal AssignFile() benutzt bevor ich mit der Datei gearbeitet habe. Also daran kann es nicht liegen.
Delete - Mo 30.08.04 21:23
Bei mir werden die nie schreibgeschützt geöffnet. Wie lautet die genaue Fehlermeldung?
Brueggendiek - Mo 30.08.04 21:31
Hallo!
In Textdateien kann man nichts verändern!
Mit Reset wird die Datei nur zum Lesen geöffnet,
Mit Rewrite wird die Datei so geöffnet, daß sie neu angelegt wird (alter Inhalt gelöscht),
mit Append werden neue Zeilen an die Datei angehängt.
Grund für dieses Verhalten ist, daß die Zeilen ja unterschiedliche Länge haben.
Abhilfe: Wenn nur einzelne Bytes ausgetauscht werden sollen, wird die Datei als "File of Byte" geöffnet. Löschen oder Einfügen von Zeichen ist da nicht möglich!
Werden Zeilen auch in der Länge verändert - reingefügt - gelöscht, kann man mit 2 Dateien arbeiten - den Inhalt der ersten Datei lesen und verändert in die zweite Datei schreiben. Ggf. nachließend Original löschen und Kopie umbenennen.
Außerdem kann man mit TStringList.ReadFromFile die komplette Datei in den Speicher laden und dort bearbeiten. Dann mit SaveToFile wieder speichern.
Bei Dateien mit fester Satzlänge sind typisierte Dateien die richtige Wahl.
Gruß
Dietmar Brüggendiek
ueberschecker - Mo 30.08.04 21:41
Danke,
wenn mich nicht alles täuscht geht das aber unter C++, oder? Dann werd ich das wohl ein bisschen umschreiben müssen.
MfG
ueberschecker - Mo 30.08.04 22:21
Hallo,
ich habe jetzt die Klasse TStringList benutzt. In dem Moment wo ich LoadFromFile() aufrufe gibt es eine Access Violation und das Programm steigt aus. Wenn ich vorher noch Create() aufrufe gibt es eine andere Access Violation. Meiner Meinung nach ist es aber sowieso Blödsinn den Constructor aufzurufen, weil der ja aufgerufen wird, sobald das Object erzeugt wird, jedenfalls ist es in C++ so. In der wunderbaren Hilfe steht jedenfalls nichts zum Thema.
Create() gehört auch zur Klasse TObject und nicht zu TStringList.
MfG
grayfox - Mo 30.08.04 23:00
hallo ueberschecker!
zu deinem beitrag möchte ich mich lieber nicht äussern, sonst artet das gleich wieder in eine diskussion aus, welche programmiersprache besser ist ;)
wenn du die stringlist so erzeugst:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| type TForm1 = class(TForm) SpeedButton1: TSpeedButton; procedure SpeedButton1Click(Sender: TObject); private MeineListe: TStringList; public end;
procedure TForm1.SpeedButton1Click(Sender: TObject); begin MeineListe:= TStringList.Create; try MeineListe.LoadFromFile(Dateiname);
MeineListe.SaveTofile(Dateiname); finally MeineListe.Free end end; |
dann sollte auch die access violation der vergangenheit angehören.
lass mal etwas programmcode sehen...
mfg, stefan
ueberschecker - Di 31.08.04 17:50
Also mein Quellcode sieht so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure TEditItemFrame.BOKClick(Sender: TObject); var i:integer; temp:string; strList:TSTringList; begin if bNewItem then begin end else begin <span style="font-weight: bold"> strList.Create; try strList.LoadFromFile('C:\Eigene Dateien\auto.txt'); strList[4*datapos]:=EditName.Text; strList[4*datapos+1]:=EditLocation.Text; strList[4*datapos+2]:=EditChars.Text; strList[4*datapos+3]:=EditNumber.Text; strList.SaveToFile(MainFrame.FileName); finally strList.Free; end </span> end; Close; MainFrame.ShowData; end; |
Schon beim Aufruf von strList.Create stürzt da Programm ab.
Moderiert von
UGrohne: Code- durch Delphi-Tags ersetzt.
zorxx - Di 31.08.04 19:07
Hallo,
ersetze mal
durch
Quelltext
1:
| strList := TStringList.Create; |
Wie es grayfox in seinem Beispiel beschrieben hat.
Gruss
zorxx
Motzi - Di 31.08.04 20:21
Das ist ein typischer Fehler von Programmierern die aus der C++-Ecke kommen.. ;)
Unter Delphi gibt es keine statischen Objekte, dh. man muss jedes Objekt erst _selbst_ erzeugen bevor man damit arbeiten kann. Jetzt gibt es aber 2 Möglichkeiten den Constructor aufzurufen:
Delphi-Quelltext
1: 2: 3: 4: 5:
| var aStringList: TStringList;
aStringList.Create; aStringList := TStringList.Create; |
Aber nur der zweite Aufruf erzeugt eine neue Instanz der TStringList-Klasse. Im ersten Fall wird der Constructor als Methode des Objekts aufgerufen, das aStringList referenziert.
Ich hab das hier im Forum schon öfters genauer beschrieben, bei Interesse einfach mal suchen... :)
ueberschecker - Di 31.08.04 20:30
Alles klar. Danke jetzt hab ich das verstanden und das Programm funtioniert auch.
MfG
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!