Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Exception der Klasse EFOpenError - finde den Fehler nicht (https://www.delphipraxis.net/136988-exception-der-klasse-efopenerror-finde-den-fehler-nicht.html)

Jiron 11. Jul 2009 21:23


Exception der Klasse EFOpenError - finde den Fehler nicht
 
Hallo alle zusammen :-)

Melde mich mal zurück.
Habe mich nun entschlossen meine Zahlen als Record und mit TFileStream zu speichern.

Aber auf welchem Weg ich das auch versuche, ich bekomme immer wieder eine Exception-Fehlermeldung. Die Fehlermeldungen betrafen immer das die Datei nicht angelegt bzw. nicht geöffnet werden kann. Im unteren Beispiel bekam ich folgende Meldung:

"Im Projekt ProjectLOTTO.exe ist eine Exception der Klasse EFOpenError aufgetreten. Meldung: 'Datei Ziehungen.dat kann nicht geöffnet werden'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen."

Kann mir einer verraten wo ich den Fehler hab ? ( hab ja gerade mit lernen angefangen )

type
TZiehung = record
z1 : integer ;
z2 : integer ;
z3 : integer ;
z4 : integer ;
z5 : integer ;
z6 : integer ;
zz : integer ;
end;
var
path: string;
Daten : file of TZiehung;
MyStream : TFileStream;

begin
// --------------------------
begin;
path := ExtractFilePath(ParamStr(0));
AssignFile(Daten,path+ 'Ziehungen.dat');
if FileExists('Ziehungen.dat') then ReSet(Daten)
else ReWrite(Daten);

begin
try
MyStream := TFileStream.Create('Ziehungen.dat',fmOpenReadWrite );
MyStream.WriteBuffer(Daten,SizeOf(TZiehung));
except
ShowMessage('Fehler beim Erstellen der Datei');
end;
MyStream.Free;
end;
// -----------------------------------------------------
end;

Noch etwas zu den Exception-Fehlermeldungen. Ich hab da in der Delphihilfe gesucht und nicht gerade viel dazu gefunden. Da hieß es nur, manche stören und welche nicht und man kann noch welche in eine Liste aufnehmen. Gibt es da eine Adresse wo auch Beispiele für ne Fehlermeldung dabei ist ( auf deutsch ) ?

Danke jetzt schon mal für eure Hilfe !
Gruß Jiron

DeddyH 11. Jul 2009 21:26

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Zitat:

Delphi-Quellcode:
MyStream := TFileStream.Create('Ziehungen.dat',fmOpenReadWrite);

Wo ist denn da der Path geblieben?

Jiron 11. Jul 2009 21:38

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Hallo DettyH

Grüß dich und danke für die schnelle Hilfe.
Wenn ich die Zeile so schreibe und hoffe das war von dir auch so gemeint :

MyStream := TFileStream.Create(Daten,path+ 'Ziehungen.dat',fmOpenReadWrite);


dann bekomme ich folgende Fehlermeldung:
[Fehler] Lotto1.pas(158): Es gibt keine überladene Version von 'Create', die man mit diesen Argumenten aufrufen kann

hm
Gruß Jiron

xZise 11. Jul 2009 21:40

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Moin Jiron,
warum Create(Daten,path...)? Es fehlt doch nur der Pfad, dann kannst du "Daten," weglassen.

MfG
xZise

DeddyH 11. Jul 2009 21:49

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Nochmal kurz zur Erklärung: relative Pfade sind "böse", da Du nicht sicher wissen kannst, wo Du die Datei überhaupt suchst. Von daher solltest Du durchgängig immer dieselbe Datei im selben Verzeichnis benutzen, d.h. am besten eine Variable deklarieren, die Du einmalig auf den kompletten Pfad zur Datei setzt und im Weiteren nur noch mit dieser arbeitest. Zu Deinem Ansatz mit dem eigenen Programmverzeichnis: das mag auf Deinem Rechner zunächst funktionieren, allerdings könntest Du ein Berechtigungsproblem bekommen. Besser wäre meiner Meinung nach das "Eigene Dateien"- oder "Anwendungsdaten"-Verzeichnis. Wie Du das bekommst, kannst Du über die Forensuche nach SHGetFolderPath herausfinden.

Jiron 11. Jul 2009 23:11

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Danke euch, nu wird die Datei angelegt und auch etwas darin gespeichert. Ich wollt mir mal ansehen, wie die Zahlen dort aneinander gereit werden, fand aber nur ne Zeichenreihe vor :-(
Ist das nur weil ich ne .dat datei angelegt habe ?
Gruß Jiron

Satty67 12. Jul 2009 07:26

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Wie Du die Datei nennst (incl. Dateiendung) hat auf das Speichern der Daten kein Einfluss. Windows entscheidet über die Dateiendung nur, welches Programm zum anzeigen gestartet wird.

Ich denke es wurde alles korrekt gespeichert, denn Dein gewähltes Format ist für das Lotto-Programm kein Problem und korrekt, aber ein z.B. Text-Editor kann nicht viel damit anfangen. Die Zahlen zusätzlich für einen Text-Editor lesbar zu speichern wäre durchaus möglich (Konvertierung, INI-Format), aber im Prinzip unnötig.

Um zu prüfen, ob die Zahlen korrekt gespeichert wurden, lies einfach die Zahlen wieder ein und lass Dir die Werte im eigenen Programm anzeigen. Alternativ wäre ein Hex-Editor ganz brauchbar, da Du damit binäre Werte korrekt anzeigen lassen kannst (zwei gute HexEditoren sind sogar hier im Forum zu finden).

***

Zum Inhalt der Datei:

Du hast 7 Integer-Werte (32bit) gespeichert, also 28 Byte im binären Format. Da Lottozahlen zw. 1 und 49 liegen, sind die meisten Werte nicht als sichtbares Zeichen darstellbar (Werte 0-31 sind Steuerzeichen in Texteditoren/Druckern)

Es ist also so, das der binäre Wert 1 nicht dem Zeichen für die Zahl "1" entspricht, die Zahl 1 hat den ASCII-Wert 49, Zahl 2 = 50 usw. Ein Text-Editor wird also die Werte 1-49 dem ASCII-Zeichen 1-49 zuordnen, was bis 31 meistens nur Kästchen gibt (da nicht darstellbar) und ab 32 mehr Satzzeichen, weil die in der ASCII-Tabelle in dem Bereich liegen. Du kannst ja mal via Google nach ASCII-Tabelle suchen um zu verstehen, wie das ganze zugeordnet ist.

Bei Deinem Record TZiehung wären auch noch zwei Änderungen möglich, die die Dateigröße verkleinern. Im aktuellen Beispiel nicht der Rede wert, aber bei einer Reihe von Ziehungen kann die Datei dadurch unnötig mit "Füllbytes" aufgebläht sein.

Die Zahlen 1-49 lassen sich mit einem Byte Darstellen (0-255). Du verwendest aber ein 32bit Integer (Größe 4 Byte), verschwendest also 3 Byte, die nicht genutzt werden.
Delphi-Quellcode:
TZiehung = packed record
  z1,
  z2,
  z3,
  z4,
  z5,
  z6,
  zz : Byte;
end;
Damit hat der Record statt 28 Byte nur die Größe von 7 Byte. Weil Delphi aber Records für optimalen Speicherzugriff optimiert und die Bytes auf Integer "auseinander ziehen" würde (32bit Ausrichtung), würde der Record wieder 28 Byte Größe haben. Damit das nicht passiert, kann man für Dateirecords den Record-Bezeichner zu packed record erweitern

Jiron 12. Jul 2009 17:43

Re: Exception der Klasse EFOpenError - finde den Fehler nich
 
Hallo Satty67

Ich danke dir für diese ausführliche Erklärung. Das diese Zeichen ASCII-Zeichen sind dacht ich mir schon. Wußte nur nicht's mit diesem binären Format an dieser Stelle anzufangen, da ich mir nicht vorstellen konnte warum die gespeicherten Zahlen so gespeichert werden sollten. Also werden alle Dateien von Delphi auf dieser Art gespeichert ?
Das Auslesen der Datei ist das nächste was ich jetzt versuche, möchte aber auch noch das Anzeigen der Recordanzahl reinbringen.
Mit dem Hinweis, mit dem Byt's bissel verschwenderisch umzugehen, haste natürlich recht. Da das Programm ja im Grunde nur aus Übungszwecken schreibe, werde ich nur die Samstagsziehungen da reinpacken. Mit den ca. 3000 Ziehungen und dann 8 Zahlen pro Ziehung, müßte ich bei ca. 100kb ankommen. Da dachte ich mir für das erste auf Integer einstellen erspart mir später eine Typumwandlung wenn mal damit gerechnet wird und es dann von Byte ins Integer geht. Ich hab mir aber deinen Hinweis für die späteren vorzunehmenden Verbesserungen mal notiert.
Deinen Tip "= packed record " werde ich gleich übernehmen, danke.

Danke noch mal für deine Bemühungen, mir das so verständlich rüberzubringen.
Gruß Jiron


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz