![]() |
EReadError beim Lesen der mit TWriter geschriebenen Daten
Hallo,
es geht immer noch um TReader/TWriter. Gestern hatte ich hier: ![]() Daten geschrieben, die ich nun lesen will. Dabei erhalte ich die EReadError Exception. Das hier ist der aktuelle Quelltext dazu:
Delphi-Quellcode:
Meine Frage ist nun, wie kann ich das Lesen bewerkstelligen?
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, FileServer, StdCtrls; type TTestRec = record Feld1: String; Feld2: String; Feld3: String; end; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; btnOk: TButton; Label1: TLabel; Label2: TLabel; Label3: TLabel; Memo: TMemo; procedure FormDestroy(Sender: TObject); procedure Edit1Change(Sender: TObject); procedure Edit2Change(Sender: TObject); procedure Edit3Change(Sender: TObject); procedure btnOkClick(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } FStream: TFileStream; FReader: TFileStream; FileReader: TReader; FFileWriter: TWriter; FTestFields: TTestRec; public { Public declarations } procedure CreateFileForWrite; procedure CreateWnd; override; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btnOkClick(Sender: TObject); begin FFileWriter.WriteString(FTestFields.Feld1); FFileWriter.WriteString(FTestFields.Feld2); FFileWriter.WriteString(FTestFields.Feld3); end; procedure TForm1.CreateFileForWrite; var Directory: String; begin Directory := GetCurrentDir; if Directory[Length(Directory)]<>'\' then Directory := Directory + '\'; FStream := TFileStream.Create(Directory+'Testfile.def', fmCreate); FFileWriter := TWriter.Create(FStream,1024); end; procedure TForm1.Edit1Change(Sender: TObject); begin FTestFields.Feld1 := Edit1.Text; end; procedure TForm1.Edit2Change(Sender: TObject); begin FTestFields.Feld2 := Edit2.Text; end; procedure TForm1.Edit3Change(Sender: TObject); begin FTestFields.Feld3 := Edit3.Text; end; procedure TForm1.FormDestroy(Sender: TObject); begin FFileWriter.Free; end; procedure TForm1.FormCreate(Sender: TObject); begin //Erzeugen des Streams zum Lesen FReader := TFileStream.Create('TestFile.def', fmOpenRead, fmShareDenyWrite); //Erzeugen des Filereader Objektes vom Typ TReader FileReader := TReader.Create(FReader, 1024); //Lesen der Daten FTestFields.Feld1 := FileReader.ReadString; FTestFields.Feld2 := FileReader.ReadString; FTestFields.Feld3 := FileReader.ReadString; FileReader.Free; //Zunächst Reader freigeben und so Datei schließen CreateFileForWrite; //Nun kann die Datei zum Schreiben geöffnet werden. //Überprüfen, ob richtig gelesen Memo.Lines.Add('Feld 1 ---> '+FTestFields.Feld1); Memo.Lines.Add('Feld 2 ---> '+FTestFields.Feld2); Memo.Lines.Add('Feld 3 ---> '+FTestFields.Feld3); end; procedure TForm1.CreateWnd; begin inherited; //CreateFileForWrite; //Diese Methode wird VOR FormCreate aufgerufen. Damit wird die Datei von anderem Prozess //verwendet, ich erhalte eine EFOpenError Exception. Deshalb in FormCreate verlegt. end; end. |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Dateiname ohne Pfadangebe vielleicht?
|
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
Delphi-Quellcode:
das hier ergänze:
FReader := TFileStream.Create(...);
Delphi-Quellcode:
erhalte ich dieselbe EFReadError Exception.
Directory := GetCurrentDir;
if Directory[Length(Directory)]<>'\' then Directory := Directory + '\'; FReader := TFileStream.Create(Directory + 'Testfile.def', fmOpenRead, fmShareDenyWrite); Was also kann ich noch tun? |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Lass Dir doch das Verzeichnis mal ausgeben.
Oder setze einen Haltepunkt und schau es dir im Debugger an. Grüße Klaus |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Welche R+ückgabe erwartest du von GetCurrentDirectory? Tipp: es muss nicht zwingend das Verzeichnis deiner Anwendung sein.
|
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
Delphi-Quellcode:
hantiert, augenscheinlich eine verlässliche Information.
GetCurrentDirectory
@dualCoreCpu
Delphi-Quellcode:
ist genauso zuverlässig wie relative Pfadangaben, und sobald auch nur ganz kurz "das passiert sowieso nicht" bei der Überlegung ob etwas schief gehen kann, aufblitzt, dann geht das garantiert schief.
GetCurrentDirectory
Entweder du nutzt selbst definierte Pfadangaben oder (meiner Meinung nach besser), du nutzt die Windows-Standardverzeichnisse. Gruß K-H |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
Von GetCurrentDir aud dem Hauptprogramm aufegerufen wewarte ich jenes Verzeichnis, in welchem meine Anwendung liegt. Hab es jetzt so gemacht: Directory := IncludeTrailingPathDelimiter(ExtractFilePath(Param str(0))); führt aber nicht zm gewünschten Erfolg. Die EReadError Exception kommt immer noch. |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Das sagt doch schon der Name: "Gib das aktuelle Verzeichnis zurück". Einmal einen Open- oder Savedialog benutzt und dabei das Verzeichnis gewechselt, schon ist das aktuelle Verzeichnis nicht mehr das Anwendungsverzeichnis. Wenn du das Anwendungsverzeichnis willst, dann guck dir in der Hilfe mal ParamStr an. Davon mal abgesehen, dass es eine ganz schlechte Idee ist irgendwelche Dateien die auch geschrieben werden sollen im Anwendunsgverzeichnis abzulegen. Da dort nur Benutzer der Administratorengruppe schreiben können. Und wen du es anders einrichtest, überschreiben sich die verschiedenen Benutzer gegenseitig die Datei.
|
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Um weiteren Zwischenfragen vorzubeugen:
Die Datei aus der ich lesen will, existiert im Pfad und enthält auch Strings, die ich nun auslesen will. Das Format ist Byte 0 Inhalt $06 vermulich eine Signatur, denn dieses Byte steht vor hedem String. 1 Längenbyte obwohl Ansistrings geschrieben werden können, lt. Hilfe, gibt es nur ein Längenbyte. 2-... der String Danach die gleiche Abfolge -> SIgnatur, Längenbyte, String. Bis Dateiende. Am Dateiende steht das letzte Zeichen des letzten Strings. |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Wie heißt die Fehlermeldung genau und in welcher Zeile tritt sie auf?
|
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
Open und Savedialog verwende ich in meinem Testprogramm nicht, aber das könnte in einer praktischen Anwendung natürlich schnell passieren. Dort werd ich wohl dann ein für Anwendungs bzw. Konfigurationsdaten ein eigenes Verzeichnis einrichten. Zitat:
Delphi-Quellcode:
FTestFields.Feld1 := FileReader.ReadString;
. |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
|
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
vielleicht hilft diese Routine:
Delphi-Quellcode:
procedure TCustomSettings.LoadFromStream(const Stream: TStream) ;
var Reader: TReader; PropName, PropValue: string; begin Reader := TReader.Create(Stream, $FFF) ; Stream.Position := 0; Reader.ReadListBegin; while not Reader.EndOfList do begin PropName := Reader.ReadString; PropValue := Reader.ReadString; SetPropValue(Self, PropName, PropValue) ; end; FreeAndNil(Reader) ; end; ![]() Grüße Klaus |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
|
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
@DualCoreCpu: Kannst du die Datei einfach mal hier anhängen? Dann kann auch mal jemand anders versuchen, die einzulesen. |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
Es hat allerdings nicht sofort funktioniert, das Lesen schon aber anschließendens Schreiben nicht. EFOpenError für den Writer. Die Ursache dafür war: Der Stream wird mit FreeAndNil(Reader) nicht mit frei gegeben. Dies muss mit Stream.Free nach FreeAndNil(Reader) separat erfolgen. Dann funktioniert auch das Schreiben in die Datei danach. |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Um die LoadFromStream() Methode von @Klaus einsetzen zu können, musste ich die Testdaten unter Deaktivierung der Lesemethode nochmals schreiben. Vorher fehlte das Listenendezeichen $00 und das ListBegin Zeichen $01. Alles andere (Kennzeichnung $06 und Längenbyte vor dem String, dann der eigentliche String, war schon vorher da. Das hier sind jetzt die wesentlichen Änderungen:
Delphi-Quellcode:
Hier FormCreate:
procedure TForm1.btnOkClick(Sender: TObject);
var Directory: String; begin Directory := GetCurrentDir; if Directory[Length(Directory)]<>'\' then Directory := Directory + '\'; FStream := TFileStream.Create(Directory+'Testfile.def', fmCreate); SaveToStream(FStream); { So hatte ich es vorher FFileWriter.WriteListBegin; FFileWriter.WriteString(FTestFields.Feld1); FFileWriter.WriteString(FTestFields.Feld2); FFileWriter.WriteString(FTestFields.Feld3); FFileWriter.WriteListEnd; } end;
Delphi-Quellcode:
und hier die Lese- und Schreibmethode:
procedure TForm1.FormCreate(Sender: TObject);
var Directory: String; begin //Erzeugen des Streams zum Lesen Directory := IncludeTrailingPathDelimiter(ExtractFilePath(Paramstr(0))); //ShowMessage(Directory); wird richtig angezeigt. FReader := TFileStream.Create(Directory+'TestFile.def', fmOpenRead, fmShareDenyWrite); //Lesen der Daten LoadFromStream(FReader); //Überprüfen, ob richtig gelesen Edit1.Text := FTestFields.Feld1; Edit2.Text := FTestFields.Feld2; Edit3.Text := FTestFields.Feld3; //Inhalt stimmt anschließend end;
Delphi-Quellcode:
Mit diesen Methoden funktioniert es jetzt. Danke wie verrückt Euch allen! :)))))
procedure TForm1.LoadFromStream(const Stream: TStream);
var Reader: TReader; begin Reader := TReader.Create(Stream, $0FFF); Reader.ReadListBegin; while not Reader.EndOfList do begin FTestFields.Feld1 := Reader.ReadString; FTestFields.Feld2 := Reader.ReadString; FTestFields.Feld3 := Reader.ReadString; end; FreeAndNil(Reader); Stream.Free; //sonst EfOpenError beim nächsten Öffnen für Schreiben!!! end; procedure TForm1.SaveToStream(const Stream: TStream); var Writer: TWriter; begin Writer := TWriter.Create(Stream, $0FFF); Writer.WriteListBegin; Writer.WriteString(Edit1.Text); Writer.WriteString(Edit2.Text); Writer.WriteString(Edit3.Text); Writer.WriteListEnd; FreeAndNil(Writer); Stream.Free; end; P.S. Wollte eigentlich nen schönen Smilie eifügen, geht aber beim Nachbearbeiten nicht. :( schade! |
AW: EReadError beim Lesen der mit TWriter geschriebenen Daten
Zitat:
Wollte mit der Meldung, Datei ist da nur Zwischenfragen vorbeugen die die Antwort verzögern. Obwohl schon klar ist, das auch der Pfad stimmen muss, worauf ich zukünftig auch besonders achten werde! :)))) Bisher habe ich das als selbstverstädlich vorausgesetzt, jetzt besser nicht mehr, obwohl es hier funktioniert hat und nicht die Ursache für mein Problem war. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:38 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