AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

"Stream Lesefehler" bei Laden via TFileStream

Offene Frage von "Gashunkification"
Ein Thema von Gashunkification · begonnen am 18. Mär 2012 · letzter Beitrag vom 19. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2   
Gashunkification

Registriert seit: 18. Mär 2012
9 Beiträge
 
#1

"Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 20:18
Hallo

Ich habe 2 Objeke, ein Item und eine ItemList.

Das Item ist wie folgt aufgebaut

Delphi-Quellcode:
  TItem = record
    ID: Integer; // wird automatisch gesetzt
    Name: String;
    Info: String;
  end; // TItem
Und die ItemList ist eine ganze Klasse, die ein array of TItem hat und dieses dann mit entsprechenden Methoden verwaltet.

Weiterhin habe ich eine Klasse TListHandler, da ich die ItemList in mehreren Forms brauche. Der Listhandler hat auch die Save und Load Methoden. Bei denen mache ich dann offensichtlich etwas falsch:

(lngth ist die Länge des Dynmaischen arrays, die ich in einer seperaten Datei (ListenName.list~) speichere )

Delphi-Quellcode:
// Load a existing List from a specific Filepath
function TListHandler.Load(const FilePath, Pathlngth: string): TItemList;
var F_Stream: TFileStream;
    F_tmp: TFileStream;
    i: Integer;
    lngth: Integer;
    Name, Info: String;
begin
  try
    F_Stream := TFileStream.Create(FilePath, fmOpenRead);
    F_tmp := TFileStream.Create(Pathlngth, fmOpenRead);
    F_tmp.ReadBuffer(lngth, SizeOf(lngth));
    for i := 0 to lngth-1 do
    begin
      Name := List.Item[i].Name;
      Info := List.Item[i].Info;
      F_Stream.ReadBuffer(Name[1], SizeOf(Name));
      F_Stream.ReadBuffer(Info[1], SizeOf(Info));
      List.Length := lngth;
    end;
  finally
    F_Stream.Free;
    F_tmp.Free;
  end; // if
end; // Load

//##############################################################################

// Save the whole List as it is to a pre-specified Filepath
procedure TListHandler.Save(const FilePath, Pathlngth: String);
var FileStream: TFileStream;
    F_tmp: TFileStream;
    i: Integer;
    lngth: Integer;
    Name, Info: String;
begin
  try
    FileStream := TFileStream.Create(FilePath, fmCreate);
    F_tmp := TFileStream.Create(Pathlngth, fmCreate);
    lngth := List.Length;
    F_tmp.WriteBuffer(lngth, SizeOf(lngth));
    for i := 0 to List.Length-1 do
    begin
      Name := List.Item[i].Name;
      Info := List.Item[i].Info;
      FileStream.WriteBuffer(Name[1], SizeOf(Name));
      FileStream.WriteBuffer(Info[1], SizeOF(Info));
    end;
  finally
    FileStream.Free;
    F_tmp.Free;
  end; // finally
end; // Save
Anbei (falls notwendig) noch die beiden Klassen TItemList und TListHandler
PS: Beide Klassen sind noch nicht fertig und entsprechende Methoden werden im letzten Zug ausgelagert.
Angehängte Dateien
Dateityp: pas U_TListHandler.pas (3,0 KB, 2x aufgerufen)
Dateityp: pas U_TItemList.pas (5,0 KB, 2x aufgerufen)

Geändert von Gashunkification (18. Mär 2012 um 20:19 Uhr) Grund: Vergessen Anhänge hochzuladen
  Mit Zitat antworten Zitat
daywalker9

Registriert seit: 1. Jan 2010
Ort: Leer
594 Beiträge
 
Delphi XE3 Professional
 
#2

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 20:33
Wenn Du Strings in einem Stream speichern willst, musst Du dir vorher die Länge mit ablegen. Da die Strings unterschiedlich lang sein können, je nachdem, was eingeben wurde.

Ich habe dafür solche Funktionen:

Delphi-Quellcode:
procedure WriteStringToStream(stream : TStream; str : String);

var
  strLength : integer;

begin
  strLength:=length(str);
  stream.Write(strLength,SizeOf(strLength));
  if strLength>0 then
    stream.Write(str[1],strLength*SizeOf(str[1]));
end;

function ReadStringFromStream(stream : TStream) : String;

var
  strLength : integer;
  hs : String;

begin
  result:='';
  stream.read(strLength,SizeOf(strLength));
  if strLength>0 then
  begin
    hs := '';
    SetLength(hs,strLength);
    stream.read(hs[1],strLength*SizeOf(hs[1]));
    result:=hs;
  end;
end;
Anders wäre es bei ShortString, der String ist dann immer 255 Zeichen lang, diesen könntest Du ohne vorheriges Abspeichern der Länge lesen und schreiben
Lars
  Mit Zitat antworten Zitat
Keldorn

Registriert seit: 6. Mär 2003
Ort: Meißen
876 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 20:45
Hallo,

du kannst auch mal einen Blick auf TWriter und TReader werfen, die haben für unterschiedliche Typen entsprechende Routinen an Bord.

Gruß Frank

Lükes Grundlage der Programmierung:
Es wird nicht funktionieren
(Murphy)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
42.982 Beiträge
 
Delphi 12 Athens
 
#4

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 21:02
Und der Stream-Fehler ist vollkommen verständlich.
Denn da ist alles falsch, was man nur falsch machen kann.

In Load:
- Wann wurde die größe der Liste "List" gesetzt?
- Wann wurde die Länge der Strings "Name" und "Info" gesetz?
- SizeOf(Name) gibt die größe des internen String-Pointers zurück. Beim Debuggen hätte dir auffallen müssen, daß 4 Byte garantiert nicht korrekt sein können.
- uvm.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Gashunkification

Registriert seit: 18. Mär 2012
9 Beiträge
 
#5

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 22:49
Okay ... ich hab das glaube ich immernoch nicht so ganz verstanden.
(Ihr müsst das entschuldigen, ich arbeite das erste Mal mit FileStreams und mein Programmierlehrer kann das nur in C#, nicht in Delphi x.x)

Habe die Save/Load mal wie folgt angepasst, aber irgendwie steht in den Variablen Name und Info beim Laden nurnoch müll ...

Delphi-Quellcode:
// Load a existing List from a specific Filepath
procedure TListHandler.Load(const FilePath: String);
var
  F_Stream: TFileStream;
  lngth: Integer;
  strlngth: Integer;
  I: Integer;
  name, Info: String;
begin
  try
    F_Stream := TFileStream.Create(FilePath, fmOpenRead);

    F_Stream.ReadBuffer(lngth, SizeOf(lngth));
    List.Length := lngth;

    for I := 0 to List.Length - 1 do
    begin

      F_Stream.ReadBuffer(strlngth, SizeOf(strlngth));
      SetLength(Name, strlngth);
      F_Stream.ReadBuffer(Name[1], strlngth*SizeOf(Name[1]));
      List.Item[i].Name := Name;

      F_Stream.ReadBuffer(lngth, SizeOf(lngth));
      SetLength(Info, lngth);
      F_Stream.ReadBuffer(Info[1], strlngth*SizeOf(Info[1]));
      List.Item[i].Info := Info;

      F_Stream.ReadBuffer(lngth, SizeOf(lngth));
      List.Item[i].ID := lngth;

    end;// for
  finally
    F_Stream.Free;
  end; // finally
end; // Load

// #############################################################################

// Save the whole List as it is to a pre-specified Filepath
procedure TListHandler.Save(const FilePath: String);
var
  F_Stream: TFileStream;
  lngth: Integer;
  strLngth: Integer;
  I: Integer;
begin
  try
    F_Stream := TFileStream.Create(FilePath, fmCreate);

    lngth := List.Length;
    F_Stream.WriteBuffer(lngth, SizeOf(lngth));
    for I := 0 to List.Length - 1 do
    begin

      strlngth := Length(List.Item[I].Name);
      F_Stream.WriteBuffer(strlngth, SizeOf(strlngth));
      F_Stream.WriteBuffer(List.Item[I].Name[1],
        strlngth*SizeOf(List.Item[I].Name[1]));

      strlngth := Length(List.Item[i].Info);
      F_Stream.WriteBuffer(strlngth, SizeOf(strlngth));
      F_Stream.WriteBuffer(List.Item[I].Info[1],
        strlngth*SizeOf(List.Item[I].Info[1]));

      lngth := List.Item[i].ID;
      F_Stream.WriteBuffer(strlngth, SizeOf(strlngth));
    end; // for

  finally
    F_Stream.Free;
  end;
end; // Save
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#6

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 23:01
Ich sehe auf Anhieb keine Fehler.
Ich gehe aber aus, dass der Fehler evt. in der Load Methode liegt:
Delphi-Quellcode:
// load
  List.Length := lngth;
Ist Length ein Property? Falls nicht -> Fehlerquelle!
Setzt der Setter von Length die Arraygröße - Falls nicht -> Fehlerquelle!
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Gashunkification

Registriert seit: 18. Mär 2012
9 Beiträge
 
#7

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 18. Mär 2012, 23:04
Ich sehe auf Anhieb keine Fehler.
Ich gehe aber aus, dass der Fehler evt. in der Load Methode liegt:
Delphi-Quellcode:
// load
  List.Length := lngth;
Ist Length ein Property? Falls nicht -> Fehlerquelle!
Setzt der Setter von Length die Arraygröße - Falls nicht -> Fehlerquelle!
Beides ist der Fall ... :

property Length: Integer read Get_Length write Set_Length;


und ... :

Delphi-Quellcode:
function TItemList.Get_Length: Integer;
begin
  // Dynamic arrays are zero-based !
  Result := High(ItemList) + 1;
end;

procedure TItemList.Set_Length(const New_Length: Integer);
begin
  SetLength(ItemList, New_Length);
end;
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#8

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 19. Mär 2012, 00:00
Wenn Du Delphi 2009 + hast solltest Du spätestens von
Bytes = Length(String)* SizeOf(Char)
ausgehen.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Gashunkification

Registriert seit: 18. Mär 2012
9 Beiträge
 
#9

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 19. Mär 2012, 00:46
Wenn Du Delphi 2009 + hast solltest Du spätestens von
Bytes = Length(String)* SizeOf(Char)
ausgehen.
genau das mache ich doch ... o__o ... Oder? xD

Delphi-Quellcode:
strlngth := Length(List.Item[i].Info); // <-------- Length(String)
F_Stream.WriteBuffer(strlngth, SizeOf(strlngth));
F_Stream.WriteBuffer(List.Item[I].Info[1],
strlngth*SizeOf(List.Item[I].Info[1])); // <-------- Length(String) * SizeOf(Char)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#10

AW: "Stream Lesefehler" bei Laden via TFileStream

  Alt 19. Mär 2012, 07:31
beim schreiben ...
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:20 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