![]() |
[TFileStream]-Speichern/Auslesen funktioniert nicht richtig
Ich wollte ein Datei Container schreiben... Gesagt getan... Allerdings hackt es schon beim Header xD
Und zwar wollte ich folgenden Header haben:
Delphi-Quellcode:
Dann speichere ich das folgendermaßen:
TXFCHeader = packed record
XFCSignature : string[3]; // XCF UserSignature : string[5]; Version : Word; FileCount : Word; Sizes : array of Cardinal; end;
Delphi-Quellcode:
Und lade es folgendermaßen:
procedure TXFCMain.SaveContainer(const AFileName: string);
var container : TFileStream; b : string; i : Word; begin FFileName := AFileName; container := TFileStream.Create(AFileName, fmCreate); try // Write Header b := FHeader.XFCSignature + FHeader.UserSignature; container.Write(Pointer(b)^, 8); container.Write(FHeader.Version, SizeOf(FHeader.Version)); container.Write(FHeader.FileCount, SizeOf(FHeader.FileCount)); i := 0; while i < FHeader.FileCount do begin container.Write(FHeader.Sizes[i], SizeOf(FHeader.Sizes[i])); inc(i); end; // Header written finally container.Free; end; end;
Delphi-Quellcode:
Problem ist, dass "b" beim laden nicht XFC sondern nichts enthält. Jedenfalls zeigt die Fehlermeldung nichts an...
procedure TXFCMain.LoadContainer(const AFileName: string);
var container : TFileStream; b : string; i : Integer; begin if FileExists(AFileName) then begin container := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite); try // Read Header b := ''; container.Read(Pointer(b)^, 3); if (b <> 'XFC') and (not FDisableNoContainerException) then // Wrong Signature raise ENoContainerException.CreateFmt(NO_XFC_SIGNATURE, [AFileName, b]); container.Read(Pointer(b)^, 5); FHeader.UserSignature := b; container.Read(FHeader.Version, SizeOf(FHeader.Version)); container.Read(FHeader.FileCount, SizeOf(FHeader.FileCount)); i := 0; while i < FHeader.FileCount do begin container.Read(FHeader.Sizes[i], SizeOf(FHeader.Sizes[i])); inc(i); end; // Header read; finally container.Free; end; end else begin raise ENoContainerException.CreateFmt(DOES_NOT_EXISTS, [AFileName]); end; end; Aber ich weis nicht, was da schief gelaufen sein könnte... |
Re: [TFileStream]-Speichern/Auslesen funktioniert nicht rich
Das Problem wird der dynamsiche Array in TXFCHeader sein
|
Re: [TFileStream]-Speichern/Auslesen funktioniert nicht rich
Warum?
Weil es wird ja erst gar nicht abgespeichert... (filecount = 0) |
Re: [TFileStream]-Speichern/Auslesen funktioniert nicht rich
Hallo Fabian,
auch Strings sind dynamische Strukturen. Wenn du keinen Speicher für den Inhalt anforderst, wirst du auch nichts laden können, sondern riskierst nur eine Schutzverletzung:
Delphi-Quellcode:
Den Inhalt von Sizes könntest du sogar "in einem Rutsch" laden. Warum verwendest du für die Signaturen keine ShortStrings?
// b := '';
SetLength (b, 3); container.Read(b[1], 3); [...] SetLength (b, 5); container.Read(b[1], 5); [...] container.Read(FHeader.FileCount, SizeOf(FHeader.FileCount)); SetLength (FHeader.Sizes, FHeader.FileCount); Gruß Hawkeye |
Re: [TFileStream]-Speichern/Auslesen funktioniert nicht rich
Zitat:
Zitat:
Zitat:
[edit]Nein => Länge immer 256 Byte ;) Und da sind die anderen Strings kleiner ;) (4 und 6 Byte)[/edit] PS: Jetzt funktionierts :D Danke Hawkeye! |
Re: [TFileStream]-Speichern/Auslesen funktioniert nicht rich
Sorry, ich habe ganz übersehen, daß du in deinem Record ja bereits ShortStrings verwendest. Diese sind nicht immer 256 Bytes lang, ihre Länge wird durch die Definition festgelegt (max. 255 Zeichen). Hinzu kommt dann noch ein Längenbyte (das "Zeichen" mit dem Index 0).
ShortStrings kannst du direkt (ohne Hilfsvariable) speichern und laden:
Delphi-Quellcode:
Das Speichern und Laden des Cardinal-Arrays könntest du so durchführen:
// Speichern
container.Write(XFCSignature[0], SizeOf(XFCSignature)); // Laden container.Read(XFCSignature[0], SizeOf(XFCSignature));
Delphi-Quellcode:
Gruß Hawkeye
// Speichern
container.Write(FHeader.FileCount, SizeOf(FHeader.FileCount)); if (FHeader.FileCount > 0) then container.Write(FHeader.Sizes[0], FHeader.FileCount * SizeOf(FHeader.Sizes[0])); // Laden container.Read(FHeader.FileCount, SizeOf(FHeader.FileCount)); SetLength (FHeader.Sizes, FHeader.FileCount); if (FHeader.FileCount > 0) then container.Read(FHeader.Sizes[0], FHeader.FileCount * SizeOf(FHeader.Sizes[0])); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:39 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