Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi 2 dimensionalen Array in Datei speichern und wieder laden (https://www.delphipraxis.net/42531-2-dimensionalen-array-datei-speichern-und-wieder-laden.html)

MisterNiceGuy 20. Mär 2005 12:55


2 dimensionalen Array in Datei speichern und wieder laden
 
Hi, ich hab einen 2d-Array

Delphi-Quellcode:
f:array[1..12,1..2] of string;
den ich in einer externen Datei speichern und wieder daraus laden möchte.

Kann mir jemand sagen wie ich das am besten anstelle?

Sprint 20. Mär 2005 13:37

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Delphi-Quellcode:
const
  IDENT_TMYARRAY = 'TMyArray';
  BUF_SIZE = 4096;
Delphi-Quellcode:
type
  TMyArray = array[1..12, 1..2] of String;
Delphi-Quellcode:
procedure SaveToFile(const MyArray: TMyArray; const FileName: String);
var
  Stream: TFileStream;
  Writer: TWriter;
  I, J: Integer;
begin
  Stream := TFileStream.Create(FileName, fmCreate);
  try
    Writer := TWriter.Create(Stream, BUF_SIZE);
    try
      Writer.WriteSignature;
      Writer.WriteIdent(IDENT_TMYARRAY);
      for I := 1 to 12 do
        for J := 1 to 2 do
          Writer.WriteString(MyArray[I, J]);
    finally
      Writer.Free;
    end;
  finally
    Stream.Free;
  end;
end;
Delphi-Quellcode:
procedure LoadFromFile(var MyArray: TMyArray; const FileName: String);
var
  Stream: TFileStream;
  Reader: TReader;
  I, J: Integer;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    Reader := TReader.Create(Stream, BUF_SIZE);
    try
      Reader.ReadSignature;
      if Reader.ReadIdent <> IDENT_TMYARRAY then
        raise Exception.Create(FileName + ' ist keine gültige Datei vom Typ TMyArray.');
      for I := 1 to 12 do
        for J := 1 to 2 do
          MyArray[I, J] := Reader.ReadString;
    finally
      Reader.Free;
    end;
  finally
    Stream.Free;
  end;
end;

MisterNiceGuy 20. Mär 2005 17:34

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
danke schön :)

mytar 27. Mär 2005 19:23

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Der Code funktioniert einwandfrei bei dateien die ich vorher mit SaveToFile erstellt habe.

Will ich jetzt aber, ich bin ja dumm, eine beliebige Datei mit LoadFromFile öffnen, passiert folgendes:
  • Delphi-Quellcode:
    Reader.ReadSignature;
    Löst bei mir die Exception "Unbekannter Stream-Typ" aus!
    (Was macht ReadSignature eigentlich, bin aus der OH nicht schlau geworden?



  • Wenn ich nun die Anweisung weglasse, löst
    Delphi-Quellcode:
    Reader.ReadIdent <> IDENT_TMYARRAY
    eine EReadError Exception aus.

    Wenn ich mit dem Debugger vorher Reader.ReadValue überprüfe gibt
    er mit rvint64, wo er mir doch eigentlich rvIdent liefern müsste!

Bitte um Hilfe!

Danke

Sprint 28. Mär 2005 10:45

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
ReadSignatur und ReadIdent prüfen, ob der Stream mit den gespeicherten Daten übereinstimmt. Damit nicht versehentlich falsche Daten geladen werden, die nicht zu deinem Array passen.

DP-Maintenance 28. Mär 2005 11:04

DP-Maintenance
 
Dieses Thema wurde von "Christian Seehase" von "Windows API" nach "Sonstige Fragen zu Delphi" verschoben.
Hat nichts mit Windows-API zu tun

Airblader 28. Mär 2005 11:12

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Die Exception dürfte zwecks des try-finally-blocks aber auch nur beim starten aus delphi raus passieren.
im kompilierten programm wird wohl keine kommen

air

mytar 28. Mär 2005 15:32

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
@Airblader: Doch! In IDE und außerhalb!

Bei einer beliebigen Datei welche die Signatur und das Ident nicht enthält,
werden die oben genannten Exceptions ausgelöst,
was kann ich dagegen machen.

Ich möchte vor allem Spider bitten, sich das anzuschauen!

Danke!

Sprint 28. Mär 2005 17:53

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von mytar
Bei einer beliebigen Datei welche die Signatur und das Ident nicht enthält,
werden die oben genannten Exceptions ausgelöst,
was kann ich dagegen machen.

Zuerst solltest du den Aufbau der Daten analysieren und dir dann darüber gedanken machen wie man diese einlesen könnte. Als nächstes solltest du versuchen deine Ideen in Schlüsselwörter umzusetzen und die Suchmaschine deiner Wahl benutzen. Sollte die Suche aussichtslos sein oder/und die eigene Umsetzung nicht zustande kommen, dann poste hier doch mal den Aufbau der Datei.

gekmihesg 28. Mär 2005 18:15

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
also das is vielleicht ein bischen einfacher:

Delphi-Quellcode:
type TMyArray = array[0..12,0..2] of integer;

procedure Save(Arr: TMyArray);
var
  f: file of TMyArray;
begin
  AssignFile(f, FILENAME);
  Rewrite(f);
  try
    Write(f,Arr);
  finally
    CloseFile(f);
  end;
end;

procedure Load(var Arr: TMyArray);
var
  f: file of TMyArray;
begin
  AssignFile(f, FILENAME);
  Reset(f);
  try
    Read(f,Arr);
  finally
    CloseFile(f);
  end;
end;

mytar 28. Mär 2005 18:51

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
@gekmihesg: Danke, aber möchte es mit Streams machen!

@Sprint: Dein Code funktioniert einwandfrei, wenn ich ihn auf Dateien die ich vorher mit SaveToFile gespeichert habe. Will ich aber irgendeine Datei, z.B. *.zip öffnen, sollte er ja
FileName + ' ist keine gültige Datei vom Typ TMyArray ausgeben.

Leider kommt er nicht zu der Exception-Instanzierung sondern wirft beim Einlesen schon nach dem ReadSignature eine Exception, lass ich diese Anweisung weg, wirft er auch in der nächten Zeile einen ERead-Exception.

Zusammenfassend: Der Compiler kommt nicht erst dorthin, um die gewünschte Exception auszuwerfen.

Was kann ich dagegen tun?

Sprint 28. Mär 2005 19:10

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von mytar
Dein Code funktioniert einwandfrei, wenn ich ihn auf Dateien die ich vorher mit SaveToFile gespeichert habe. Will ich aber irgendeine Datei, z.B. *.zip öffnen, sollte er ja
FileName + ' ist keine gültige Datei vom Typ TMyArray ausgeben.

Also geht es dir jetzt um eine Fehlerbehandlung?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const
  IDENT_TMYARRAY = 'TMyArray';
  BUF_SIZE = 4096;
type
  TMyArray = array[1..12, 1..2] of String;

  procedure LoadFromFile(var MyArray: TMyArray; const FileName: String);
  var
    Stream: TFileStream;
    Reader: TReader;
    I, J: Integer;
  begin
    Stream := TFileStream.Create(FileName, fmOpenRead);
    try
      Reader := TReader.Create(Stream, BUF_SIZE);
      try
        Reader.ReadSignature;
        if Reader.ReadIdent <> IDENT_TMYARRAY then
          raise Exception.Create(FileName + ' ist keine gültige Datei vom Typ TMyArray.');
        for I := 1 to 12 do
          for J := 1 to 2 do
            MyArray[I, J] := Reader.ReadString;
      finally
        Reader.Free;
      end;
    finally
      Stream.Free;
    end;
  end;

var
  MyArray: TMyArray;
begin

  if OpenDialog1.Execute then
  begin
    try
      LoadFromFile(MyArray, OpenDialog1.FileName);
    except
      on E: Exception do
        ShowMessage('Folgender Fehler ist aufgetreten: ' + E.Message);
    end;
  end;

end;

mytar 29. Mär 2005 16:26

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Habs getestet. Funktioniert leider trotzdem nicht!

Die Anweisungen in der letzten if manipuliert ja glaub ich nur
die Exception-Message!

Ich glaub du hast mich falsch verstanden, muss mich dafür entschuldigen!

Wie bereits gesagt funktioniert der Code einwandfrei, für dateien die
die Signature und den Ident enthalten.

Bei anderen beliebigen Dateien, wie einem jpeg z.b., wird bereits nach dem
ReadSignature eine Exception "Unbekanntes Stream-Format" geworfen, was ich ja
auf keinen Fall will. Ich möchte ja bis zu "meiner" Exception die ich selbst auslöse.

Lass ich nun das ReadSignature weg, wirft er mir statt der einen Exception "Unbekannter
Eigenschaftswert".

D.h. ReadSignature und ReadIdent lösen bereits Exceptions aus. Der Compiler kommt
gar nicht mehr zur gewünschten auszulösenden Exception!

Bitte um Hilfe!

Danke

P.S. Bitte den Code einmal auf einen beliebige Datei testen! Bei mir werden dann leider die beiden ungewünschten Exceptions ausgelöst!

Ratte 29. Mär 2005 16:30

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Welche gewünschte Exeption?

Ratte

Khabarakh 29. Mär 2005 16:37

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von Ratte
Welche gewünschte Exeption?

Ratte

Delphi-Quellcode:
raise Exception.Create(FileName + ' ist keine gültige Datei vom Typ TMyArray.');
Aber eigentlich kann doch keine (interne, also nicht eigene) Exception in einem try-Block ausgelöst werden :gruebel: .

mytar 29. Mär 2005 16:47

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
ReadSignature löst sehrwohl eine Exception aus, sowie ReadIdent!

Der Try-Block verhilft nur zu einer geregelten Fehlerbehandlung (glaub ich) !


Erbitte weiter Hilfe!

Sprint 29. Mär 2005 17:01

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von mytar
Bei anderen beliebigen Dateien, wie einem jpeg z.b., wird bereits nach dem
ReadSignature eine Exception "Unbekanntes Stream-Format" geworfen, was ich ja
auf keinen Fall will. Ich möchte ja bis zu "meiner" Exception die ich selbst auslöse.

Du kannst die Exception doch so abfangen, wie ich es in dem Beispiel mit dem OpenDialog gemacht habe.

mytar 29. Mär 2005 18:59

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Statt "Unbekanntes Stream-Format" gibt er mir halt "Folgender Fehler ist aufgetreten: Unbekanntes Stream-Format" aus.

Bitte probier es mit einer beliebigen Datei, du wirst sehen, er gibt dir diese Meldung aus. Diese Exception wird vom ReadSignature ausgelöst, "Unbekannter Eigenschaftwert" von ReadIdent vom Type EReadError wenn ein unbekannter ReadValue im Objekt vorhanden ist!

Bitte unbedingt testen! Danke!

Sprint 29. Mär 2005 19:04

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von mytar
Statt "Unbekanntes Stream-Format" gibt er mir halt "Folgender Fehler ist aufgetreten: Unbekanntes Stream-Format" aus.

Ich weiß immer noch nicht was du willst. Wenn die Datei nicht gelesen werden kann, dann wird halt ein Fehler ausgelöst. Diesen kannst du abfangen. Auswerten. Anzeigen oder halt auch nicht.

Wo genau liegt jetzt dein Problem?

mytar 29. Mär 2005 19:07

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Mein Ziel: LoadFromFile soll für jeden Dateityp funktionieren.
Falls er nicht vom Format IDENT_TMYARRAY ist, soll die gewünschte Exception ausgelöst
werden, ansonsten der Inhalt in die Variable MyArray geladen werden.

Am besten ist wirklich das Ziel mitteilen! :wall:

Sprint 29. Mär 2005 19:10

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Und das macht der SourceCode ja auch.

mytar 29. Mär 2005 19:21

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Wenn ich das ausführe stimmt das nur teilweise.
Bei Dateien die ich vorher mit der Speicherroutine abgespeichert habe,
funktioniert es einwandfrei und die daten werden eingelesen.

Mein Programm sollte eben so benutzerfreundlich wie möglich sein,
dass heißt wenn man ein jpeg öffnen will, so einen schöne Fehlermeldung kommen.

wenn ich jetzt eben ein jpeg öffnen dass, ja keine Signature und auch kein Ident
enthält, wird bei diesem beiden read-Anweisungen eine Exception ausgelöst.

Das will ich aber nicht!

wahrscheinlich bin ich hier wohl der depp! :-D

Sprint 29. Mär 2005 19:37

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von mytar
Wenn ich das ausführe stimmt das nur teilweise.
Bei Dateien die ich vorher mit der Speicherroutine abgespeichert habe,
funktioniert es einwandfrei und die daten werden eingelesen.

Das ist richtig.

Zitat:

Mein Programm sollte eben so benutzerfreundlich wie möglich sein,
dass heißt wenn man ein jpeg öffnen will, so einen schöne Fehlermeldung kommen.
Kommt ja auch. (Beispiel von mir mit dem OpenDialog. Aussehen der Fehlermeldung kannst du selber bestimmen)

Zitat:

wenn ich jetzt eben ein jpeg öffnen dass, ja keine Signature und auch kein Ident
enthält, wird bei diesem beiden read-Anweisungen eine Exception ausgelöst.
Du willst also Daten aus einer JPEG Datei lesen? Oben hast du doch geschrieben das eine Fehlermeldung kommen soll. :?

Zitat:

Das will ich aber nicht!
Was willst du nicht?

mytar 29. Mär 2005 20:03

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Nein, ich meine das Prog soll so idiotensicher sein, dass auch bei einer jpeg datei eine Fehlermeldung kommt, dass dieses Format nicht unterstützt wird.

Die Lösung mit der äußeren Exception hab ich jetzt geknissen. Halte es aber für unschön. Bitte nimms nicht böse. Vielleicht gehts, anders auch noch!

Wenn es auch für beliebige Dateien ohne äußere Exception - Klausel funktionieren würde, wäre echt toll.

Kannst du mir noch weiterhelfen, oder kann ich mir diese Lösung mit TReader und TWriter abschminken?
:-D

Sprint 30. Mär 2005 02:22

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
Zitat:

Zitat von mytar
Die Lösung mit der äußeren Exception hab ich jetzt geknissen. Halte es aber für unschön. Bitte nimms nicht böse. Vielleicht gehts, anders auch noch!
Wenn es auch für beliebige Dateien ohne äußere Exception - Klausel funktionieren würde, wäre echt toll.

Ich glaube du hast mein OpenDialog Beispiel nicht verstanden. Du kannst die Fehlermeldung so anpassen wie du möchtest.
Schau dir mal das on E: Exception do zwischen except und end genauer an.

mytar 30. Mär 2005 07:45

Re: 2 dimensionalen Array in Datei speichern und wieder lade
 
OK! Danke!


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:59 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