Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Record in FileStream schreiben (https://www.delphipraxis.net/42193-record-filestream-schreiben.html)

Die Muhkuh 15. Mär 2005 15:08


Record in FileStream schreiben
 
Hi,

ich hab hier schon danach gesucht und bin auf einen Beitrag von Luckie gestoßen. Seine Lösung hat auch fast geklappt^^.

Also, erstma bisschen Code:

Delphi-Quellcode:
TTEDInfo = record
    CORE_VERSION: String;
    CONTAINER_VERSION: String;
    DOCUMENT_VERSION: String;
    EDITOR_VERSION: String;
    TED_VERSION: String;
    SAVE_TEXT: String;
  end;

[...]
function TContainer.ReadTedInfoFromStream(F: TStream): TTEDInfo;
begin
  F.ReadBuffer(Result, SizeOf(TTEDInfo)); // <- Da
end;

procedure TContainer.WriteTedInfoToStream(F: TStream; aInfo: TTEDInfo);
begin
  F.WriteBuffer(aInfo, SizeOf(TTEDInfo));
end;
An der markierten Stelle bekomme ich einen Stream-Lesefehler.

Woran könnte der Fehler liegen?

jfheins 15. Mär 2005 15:11

Re: Record in FileStream schreiben
 
Weil die Strings eine dynamische Länge haben, kannst du nicht einfach so speichern, du musst vorher die länge des strings speichern, dann den string usw.


Quelle: http://www.dsdt.info/tutorials/streams/?page=2

Delphi-Quellcode:
Len := Length(Daten[I].Name);
      Stream.Write(Len, SizeOf(Len));
      Stream.Write(PChar(Daten[I].Name)^, Len);

alcaeus 15. Mär 2005 15:12

Re: Record in FileStream schreiben
 
Hallo Manuel,

AFAIR geht das nicht, weil die Strings keine fixe Länge haben.

Greetz
alcaeus

Die Muhkuh 15. Mär 2005 15:13

Re: Record in FileStream schreiben
 
Ok,

ich könnte ja

Delphi-Quellcode:
TTEDInfo = record
    CORE_VERSION: String[255];
    CONTAINER_VERSION: String[255];
    DOCUMENT_VERSION: String[255];
    EDITOR_VERSION: String[255];
    TED_VERSION: String[255];
    SAVE_TEXT: String[255];
  end;
Aber, dann gehts auch nich.

TStringlist 15. Mär 2005 17:06

Re: Record in FileStream schreiben
 
Hi, bist du sicher, dass der FileStream auch aktuell genug Inhalt intus hat, bzw. die Property "Position" nicht schon am Ende dieses Inhaltes steht?


(PS. Das Topic lautet: "Record in FileStream schreiben" ...aber der Error taucht jetzt beim Auslesen des Streams (hinein in einen Buffer) auf? (Allerdings ist diese Funktionsbezeichnung ("ReadBuffer") hier imo insgesamt aber auch irgendwie etwas irreführend und müsste eigentlich besser ReadIntoBuffer o.ä. heißen..))

Die Muhkuh 16. Mär 2005 13:08

Re: Record in FileStream schreiben
 
Hi,

die Sache ist folgende:

Ich schreibe wie gesagt, diesen Record TTEDInfo in eine Datei. Wenn nun jemand mit meinem Programm diese Datei öffnet, dort aber andere _VERSION drinn sein sollten, soll der Benutzer informiert werden, dass der Benutzer eine alte Version hat oder er ein altes Dokument geöffnet hat.

Auselesen:

Delphi-Quellcode:
procedure TContainer.Load(const FileName: String);
var
  Doc: TDocument;
  Ext: String;
  Stream: TFileStream;
  StringStream: TStringStream;
  Info: TTEDInfo;
begin
  Doc := GetDoc;

  Ext := ExtractFileExt(FileName);

  if LowerCase(Ext) <> '.ted' then
  begin
    case Doc.FEditorType of
      etRich:
        TRxRichEdit(Self.FRichEdits[Doc.Number]).Lines.LoadFromFile(FileName);
      etSyn: TSynEdit(Self.FSynEdits[Doc.Number]).Lines.LoadFromFile(FileName);
    end;
  end
  else
  begin
    try
      Stream := TFileStream.Create(FileName, fmCreate);
      StringStream := TStringStream.Create('');

      Info := ReadTedInfoFromStream(Stream);

      ShowMessage(Info.CORE_VERSION); // Das is nur ma zum Test
      ShowMessage(Info.SAVE_TEXT); // Das auch^^
    finally
      FreeAndNil(Stream);
      FreeAndNil(StringStream);
    end;
  end;
end;
Speichern:

Delphi-Quellcode:
procedure TContainer.Save(const FileName: String);
var
  Doc: TDocument;
  Ext: String;
  Stream: TFileStream;
  StringStream: TStringStream;
begin
  Doc := GetDoc;

  Ext := ExtractFileExt(FileName);

  if LowerCase(Ext) <> '.ted' then
  begin
    case Doc.FEditorType of
      etRich:
        TRxRichEdit(Self.FRichEdits[Doc.Number]).Lines.SaveToFile(FileName);
      etSyn: TSynEdit(Self.FSynEdits[Doc.Number]).Lines.SaveToFile(FileName);
    end;
  end
  else
  begin
    try
      Stream := TFileStream.Create(FileName, fmCreate);
      StringStream := TStringStream.Create('');

      WriteTedInfoToStream(Stream, TedInfo);
    finally
      FreeAndNil(Stream);
      FreeAndNil(StringStream);
    end;
  end;
end;
Deswegen wollte ich das so speichern:

- TEDInfo
- Eigentlicher Inhalt der Datei (wird im Moment noch nicht gespeichert)

TStringlist 16. Mär 2005 15:08

Re: Record in FileStream schreiben
 
Hi, der Fehler liegt wohl darin, dass du beim Auslesen in TContainer.Load den FileStream dort dann mit einem fmCreate als Mode-Parameter erzeugst. (fmCreate wirkt aber eher wie ein 'Rewrite' bei den normalen Fileoperationen ...mit dem du also einen File dann zum Be/Über-Schreiben öffnest und damit quasi den bisherigen Inhalt löschst). Mit einem fmOpenRead müsste es dann eigentlich klappen.

Die Muhkuh 16. Mär 2005 15:13

Re: Record in FileStream schreiben
 
Hi,

thx! Daran lags :-)


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