Autor |
Beitrag |
Mashalla
      
Beiträge: 48
Windows 7 Professional
Delphi 7 Enterprise, Turbo Delphi Explorer 2006
|
Verfasst: Di 02.02.10 20:56
Ich will mittels TFileStream Informationen in eine Datei schreiben und diese dann speichern. Habe bisher kaum mit TFileStream gearbeitet, mit den Write und Read Methoden noch gar nicht. Problem ist jetzt, dass die gespeicherte Datei eine Größe von 0 Byte hat und ich weiß ned, woran es liegt. TCatalogue ist eine von ObjectList abgeleitete Klasse, TVoc is auch was eigenes. Die erste ShowMessage funktioniert, die 2. dagegen bleibt leer. Compiler meckert nicht, fehlende Zugriffsrechte oder sowas sinds auch nicht. Kann mir jemand dabei helfen?
PS: Warum erkennt mein Compiler eigentlich die Mode-Parameter "fmShareExclusive" und so nicht? Habe Classes und Contnrs eingebunden ...
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73:
| procedure TCatalogue.SaveToFile(FName: string); var Stream: TFileStream; I: Integer; Voc: TVoc; begin try try Stream := TFileStream.Create(FName, fmCreate); for I := 0 to self.Items - 1 do begin Voc := (self.Items[I]) as TVoc; Stream.WriteBuffer(Voc.Source, SizeOf(Voc.Source)); Stream.WriteBuffer(Voc.Dest, SizeOf(Voc.Dest)); Stream.WriteBuffer(Voc.Desc, SizeOf(Voc.Desc)); end; except end; finally Stream.Free; end; end;
procedure TCatalogue.LoadFromFile(FName: string); var Stream: TFileStream; Voc: TVoc; Source, Dest, Desc: string; begin try try Stream := TFileStream.Create(FName, fmCreate); Stream.Position := 0; Stream.Read(Source, SizeOf(Source)); Stream.Read(Dest, SizeOf(Dest)); Stream.Read(Desc, SizeOf(Desc)); Voc := TVoc.Create(Source, Dest, Desc); self.Add(Voc); except end; finally Stream.Free; end; end;
procedure TMainForm.FormCreate(Sender: TObject); var MyArray: array[0..2] of string; MyCat, MyCat2: TCatalogue; MyVoc, MyVoc2: TVoc;
begin ...
MyVoc := TVoc.Create('a','b'); MyCat := TCatalogue.Create(MyVoc); MyCat2 := TCatalogue.Create; ShowMessage(MyVoc.Source); MyCat.SaveToFile('Test.abc'); MyCat2.LoadFromFile('Test.abc'); ShowMessage(IntToStr(SizeOf(MyCat2))); MyVoc2 := (MyCat2.First) as TVoc; ShowMessage(MyVoc2.Source); |
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 02.02.10 21:14
Moin!
Mashalla hat folgendes geschrieben : | TCatalogue ist eine von ObjectList abgeleitete Klasse, TVoc is auch was eigenes. |
Zeig mal die Deklarationen der Objekte, das ist nicht ganz unwesentlich bei solchen Problemen.
Mashalla hat folgendes geschrieben : | PS: Warum erkennt mein Compiler eigentlich die Mode-Parameter "fmShareExclusive" und so nicht? Habe Classes und Contnrs eingebunden ... |
Die Konstanten werden in SysUtils deklariert (D7).
Das hier geht allerdings ganz sicher nicht: Mashalla hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TCatalogue.LoadFromFile(FName: string); var Stream: TFileStream; Voc: TVoc; Source, Dest, Desc: string; begin try try Stream := TFileStream.Create(FName, fmCreate); Stream.Position := 0; Stream.Read(Source, SizeOf(Source)); Stream.Read(Dest, SizeOf(Dest)); Stream.Read(Desc, SizeOf(Desc)); Voc := TVoc.Create(Source, Dest, Desc); | |
Wie gesagt, zeig mal die Deklarationen deiner Objekte, dann sehen wir weiter.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Mashalla 
      
Beiträge: 48
Windows 7 Professional
Delphi 7 Enterprise, Turbo Delphi Explorer 2006
|
Verfasst: Di 02.02.10 22:06
TCatalogue
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| type TCatalogue = class(TObjectList)
private
public
constructor Create(FVoc: TVoc); overload;
constructor Create; overload;
procedure SaveToFile(FName: string);
procedure LoadFromFile(FName: string);
end; |
TVoc
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| type TVoc = class
private
FSource: String; FDest: String; FDesc: String; procedure setVocSource(newSource: string);
procedure setVocDest(newDest: string);
procedure setVocDesc(newDesc: string);
public
constructor Create(Source: string; Dest: string; Desc: string); overload; constructor Create(Source: string; Dest: string); overload;
property Source: string read FSource write setVocSource; property Dest: string read FDest write setVocDest; property Desc: string read FDesc write setVocDesc;
end; |
Ist das das gewünschte? Schreibe später noch 2-3 Dinge dazu
Nachtrag:
Ich will die Objekte einer ObjectList speichern. Da es hierfür nix einfaches fertiges gibt, dachte ich, ich schreibe einfach die einzelnen Objektattribute in einen Stream und erstelle beim Laden die Objekte neu und lade sie in die Containerliste. Soweit zum Plan
Also 2k9+ interessiert mich aktuell nicht wirklich, hab mich bezüglich Unicode usw auch noch nicht schlau gemacht
Wie gesagt, hab nicht genau ne Peilung, wie FileStream funktioniert. Was bringt mir der Buffer? Wird dorthinein gespeichert, was gelesen wird bzw dort heraus geschrieben? Finde zwar genügend Beispiele, aber klar wirds mir dadurch auch nicht. Und vor allem, dass der Buffer typenlos ist, macht mich stutzig, kenne sowas bisher nicht...
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 02.02.10 23:44
Moin!
Hier mal ein Vorschlag, wie ich das umgesetzt hätte:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191:
| uses ..., Contnrs;
type TVoc = class(TObject) private FSource: AnsiString; FDest: AnsiString; FDesc: AnsiString; public constructor Create(const ASource, ADest: AnsiString; const ADesc: AnsiString = ''); constructor CreateFromStream(AStream: TStream); property Source: AnsiString read FSource write FSource; property Dest: AnsiString read FDest write FDest; property Desc: AnsiString read FDesc write FDesc; procedure WriteToStream(AStream: TStream); procedure ReadFromStream(AStream: TStream); function Dump: AnsiString; end;
TCatalogue = class(TObjectList) public procedure SaveToStream(AStream: TStream); procedure LoadFromStream(AStream: TStream); procedure SaveToFile(const FName: String); procedure LoadFromFile(const FName: String); end;
TForm1 = class(TForm) btnAdd: TButton; btnShow: TButton; btnLoad: TButton; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; btnSave: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btnAddClick(Sender: TObject); procedure btnShowClick(Sender: TObject); procedure btnLoadClick(Sender: TObject); procedure btnSaveClick(Sender: TObject); private public Catalogue: TCatalogue; end;
implementation
function WriteString(const AString: AnsiString; AStream: TStream): Integer; var Len: Integer; begin Len := Length(AString); AStream.Write(Len,SizeOf(Len)); Result := AStream.Write(PAnsiChar(AString)^,Len); end;
function ReadString(var AString: AnsiString; AStream: TStream): Integer; var Len: Integer; begin AStream.Read(Len,SizeOf(Len)); SetLength(AString,Len); Result := AStream.Read(PAnsiChar(AString)^,Len); end;
constructor TVoc.Create(const ASource, ADest: AnsiString; const ADesc: AnsiString = ''); begin inherited Create; FSource := ASource; FDest := ADest; FDesc := ADesc; end;
constructor TVoc.CreateFromStream(AStream: TStream); begin inherited Create; ReadFromStream(AStream); end;
function TVoc.Dump: AnsiString; begin Result := Format('S:%s, D:%s, C:%s',[FSource,FDest,FDesc]); end;
procedure TVoc.ReadFromStream(AStream: TStream); begin ReadString(FSource,AStream); ReadString(FDest,AStream); ReadString(FDesc,AStream); end;
procedure TVoc.WriteToStream(AStream: TStream); begin WriteString(FSource,AStream); WriteString(FDest,AStream); WriteString(FDesc,AStream); end;
procedure TCatalogue.LoadFromFile(const FName: String); var FS: TFileStream; begin FS := TFileStream.Create(FName,fmOpenRead or fmShareDenyWrite); try LoadFromStream(FS); finally FS.Free; end; end;
procedure TCatalogue.LoadFromStream(AStream: TStream); var ItemsToLoad, i: Integer; begin Clear; AStream.Read(ItemsToLoad,SizeOf(ItemsToLoad)); for i := 0 to ItemsToLoad-1 do Add(TVoc.CreateFromStream(AStream)); end;
procedure TCatalogue.SaveToFile(const FName: String); var FS: TFileStream; begin if FileExists(FName) then DeleteFile(FName); FS := TFileStream.Create(FName,fmCreate or fmShareExclusive); try SaveToStream(FS); finally FS.Free; end; end;
procedure TCatalogue.SaveToStream(AStream: TStream); var ItemsToWrite, i: Integer; begin ItemsToWrite := Count; AStream.Write(ItemsToWrite,SizeOf(ItemsToWrite)); for i := 0 to Count-1 do TVoc(Items[i]).WriteToStream(AStream); end;
procedure TForm1.FormCreate(Sender: TObject); begin Catalogue := TCatalogue.Create; end;
procedure TForm1.FormDestroy(Sender: TObject); begin Catalogue.Free; end;
procedure TForm1.btnAddClick(Sender: TObject); var Source, Dest, Desc: AnsiString; begin Source := InputBox('Add','Source','Source'); Dest := InputBox('Add','Dest','Dest'); Desc := InputBox('Add','Desc',''); Catalogue.Add(TVoc.Create(Source,Dest,Desc)); end;
procedure TForm1.btnShowClick(Sender: TObject); var i: Integer; begin for i := 0 to Catalogue.Count-1 do ShowMessage(TVoc(Catalogue.Items[i]).Dump); end;
procedure TForm1.btnLoadClick(Sender: TObject); begin if OpenDialog1.Execute then Catalogue.LoadFromFile(OpenDialog1.FileName); end;
procedure TForm1.btnSaveClick(Sender: TObject); begin if SaveDialog1.Execute then Catalogue.SaveToFile(SaveDialog1.FileName); end; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Mashalla 
      
Beiträge: 48
Windows 7 Professional
Delphi 7 Enterprise, Turbo Delphi Explorer 2006
|
Verfasst: Mi 03.02.10 00:08
Naja, immerhin sind meine Kommentare besser XD
Danke, hast du des jetzt schnell runtergetippt? Falls ja, weiß ich ja, wo ich mal hinkommen muss =) Aber warum löschst du beim Speichern in die Datei die Datei, wenn sie bereits existiert? Filestream.Create öffnet sie doch dann ... oder würde der dann dahinter die Daten einfügen?
|
|
Xentar
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Mi 03.02.10 00:10
Mashalla hat folgendes geschrieben : | Danke, hast du des jetzt schnell runtergetippt? Falls ja, weiß ich ja, wo ich mal hinkommen muss =) Aber warum löschst du beim Speichern in die Datei die Datei, wenn sie bereits existiert? Filestream.Create öffnet sie doch dann ... oder würde der dann dahinter die Daten einfügen? |
Er würde die Daten schon überschreiben statt anhängen. Aber, wenn die "neuen" Daten kürzer sind als die alten, bleibt nen Überhang von alten Daten zurück.
_________________ PROGRAMMER: A device for converting coffee into software.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 03.02.10 00:17
Moin!
Mashalla hat folgendes geschrieben : | Danke, hast du des jetzt schnell runtergetippt? |
Jup, hab aber zwischendurch noch schnell was gegessen.
Mashalla hat folgendes geschrieben : | Falls ja, weiß ich ja, wo ich mal hinkommen muss =) |
Nunja  eigentlich bin ich ja der keinen-Quelltext-liefern-Prediger  aber da du bereits Eigeninitiative gezeigt hast und das Thema Streams brauchbar umsetzen wirklich nicht ganz einfach ist, hilft ein komplettes Beispiel mehr, als da einzeln an den Funktionen zu popeln.  Das ist also kein Standard hier, sondern eine Ausnahme wegen der Streams.
Mashalla hat folgendes geschrieben : | Aber warum löschst du beim Speichern in die Datei die Datei, |
Hat Xentar ja schon beantwortet.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 03.02.10 00:46
Man kann aber auch nach dem Schreiben St4ream.Size := Stream.Position; setzen. Das hat den gleichen Effekt, vermeidet aber im Zweifelsfalle, dass die Datei auf dem Datenträger kreuz-und-Quer-Alloziiert wird und beugt damit der Defragmentierung etwas vor.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|