Autor Beitrag
Lemmingman2005
Hält's aus hier
Beiträge: 12

Windows XP, Gentoo Linux 2005.0
Delphi 7.0 Enterprise
BeitragVerfasst: So 17.07.05 13:50 
Hi!

ich weiß, mit FileStreams schlägt sich hier fast jeder zweite rum, trotzdem: zu meinem Problem habe ich hier keine Lösung gefunden.
Folgendes: ich habe eine Klasse, in der ein paar Informationen in Form von Strings, Integern und Bytes hinterlegt sind. Diese sollen mit Hilfe von TFileStream in eine Datei gespeichert werden. Um die Aufrufe von Lade und Speicherroutinen zu vereinfachen, habe ich einen Record definiert, der die zu speichernden Informationen kennt.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
TTaskFileStruct = record
     qstr, astr, msg_correct, msg_fail: string;
     parts, tries: byte;
  end;


Das speichern ansich funktioniert ja wunderbar, doch das laden nicht.

Um keine Verwirrungen zu provizieren, hinterlege ich hier am besten mal den ganzen Quelltext von meiner Klasse und den Aufrum zum Speichern.

ausblenden volle Höhe Delphi-Quelltext
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:
unit uTask;

interface

uses
  Windows, SysUtils, Classes,Messages, Dialogs;


type
  TTaskFileStruct = record
     qstr, astr, msg_correct, msg_fail: string;
     parts, tries: byte;
  end;

  TTask = class (TObject)
  private
    //members for identification
    mName: string;
    mID: integer;
    //members for question-handling
    m_quest_str: string;
    m_quest_parts: byte;
    m_quest_tries: byte;

    //members for answer-handling
    m_answer_str: string;

    //members for message output
    m_msg_correct: string;
    m_msg_fail: string;
    //members for file-io
//    mFile: TTaskFile;
//    mStruct: TTaskFileStruct;

    function makeRecord: TTaskFileStruct;
    procedure updatedata(struct: TTaskfilestruct);
  public
    constructor Create;
    destructor Destroy; override;

    procedure LoadTask (Filename: string);
    procedure SaveTask (Filename: string);
    procedure SubmitStruct(struct: TTaskFileStruct);

  published
    property Name: string read mName;
    property ID: integer read mID;
  end;

implementation

function TTask.makeRecord: TTaskFileStruct;
begin
  result.qstr := m_quest_str;
  result.parts := m_quest_parts;
  result.tries := m_quest_tries;
  result.astr := m_answer_str;
  result.msg_correct := m_msg_correct;
  result.msg_fail := m_msg_fail;
end;

procedure TTask.updatedata(struct: TTaskfilestruct);
begin
  m_quest_str := struct.qstr;
  m_quest_parts := struct.parts;
  m_quest_tries := struct.tries;
  m_answer_str := struct.astr;
  m_msg_correct := struct.msg_correct;
  m_msg_fail := struct.msg_fail;
end;

constructor TTask.Create;
begin
  inherited;
end;

destructor TTask.Destroy;
begin
  inherited;
end;

procedure TTask.LoadTask (Filename: string);
var s: TTaskFileStruct;
    fs: TFileStream;
    len: integer;
    str: string;
    byt: byte;
begin
  fs := TFileStream.Create (Filename, fmOpenRead);
  try
    fs.ReadBuffer(len, sizeof(integer));
    if len <> sizeof(s) then begin
      raise Exception.Create('Invalid file-data in byte 0');
      exit;
    end;
    fs.readbuffer(len, sizeof(integer));
    fs.readbuffer(str, len*sizeof(char));
    s.qstr := str;
    fs.readbuffer(byt, sizeof(byte));
    s.parts := byt;
    fs.readbuffer(byt, sizeof(byte));
    s.tries := byt;
    fs.readbuffer(len, sizeof(integer));
    fs.readbuffer(str, len*sizeof(char));
    s.astr := str;
    fs.readbuffer(len, sizeof(integer));
    fs.readbuffer(str, len*sizeof(char));
    s.msg_correct := str;
    fs.readbuffer(len, sizeof(integer));
    fs.readbuffer(str, len*sizeof(char));
    s.msg_fail := str;
    updateData(s);
    showMessage('Loading -> OK');
  finally
    FreeAndNil(fs);
  end;

end;

procedure TTask.SaveTask (Filename: string);
var s: TTaskFileStruct;
    fs: TFileStream;
    len: integer;
    str: string;
    byt: byte;
begin
  s := makeRecord;
  fs := TFileStream.Create(Filename, fmCreate);
  try
    s := makeRecord;
    len := sizeof(s);
    fs.writebuffer(len, sizeof(integer));
    str := s.qstr;
    len := length(str);
    fs.WriteBuffer(len, sizeof(integer));
    fs.writebuffer(str, len*sizeof(char));
    byt := s.parts;
    fs.WriteBuffer(byt, sizeof(byte));
    byt := s.tries;
    fs.WriteBuffer(byt, sizeof(byte));
    str := s.astr;
    len := length(str);
    fs.WriteBuffer(len, sizeof(integer));
    fs.writebuffer(str, len*sizeof(char));
    str := s.msg_correct;
    len := length(str);
    fs.WriteBuffer(len, sizeof(integer));
    fs.writebuffer(str, len*sizeof(char));
    str := s.msg_fail;
    len := length(str);
    fs.WriteBuffer(len, sizeof(integer));
    fs.writebuffer(str, len*sizeof(char));
  finally
    FreeAndNil(fs);
  end;
end;

procedure TTask.SubmitStruct(struct: TTaskFileStruct);
begin
  m_quest_str := struct.qstr;
  m_quest_parts := struct.parts;
  m_quest_tries := struct.tries;
  m_answer_str := struct.astr;
  m_msg_correct := struct.msg_correct;
  m_msg_fail := struct.msg_fail;
end;

end.


jetzt noch den Aufruf für TTask.SaveTask

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Button1Click(Sender: TObject);
var t: TTask;
    struct: TTaskFileStruct;
begin
  t := TTask.Create;
  struct.qstr := 'Was is was?';
  struct.parts := 1;
  struct.tries := 1;
  struct.astr := 'Ich bin du!';
  struct.msg_correct := 'Bisch der Held!';
  struct.msg_fail := 'Nee.....so net. Des iss schon mit Denken!';
  t.SubmitStruct(struct);
  t.SaveTask('D:\Test.dat');
  t.Free;

end;


Kann mir jemand sagen, warum die Strings beim Laden nicht richtig gelesen werden?
Danke schonmal
Gruß Lemmingman
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: So 17.07.05 13:57 
Benutze TReader und TWriter.

_________________
Ciao, Sprint.
Lemmingman2005 Threadstarter
Hält's aus hier
Beiträge: 12

Windows XP, Gentoo Linux 2005.0
Delphi 7.0 Enterprise
BeitragVerfasst: So 17.07.05 14:03 
Werd's mal testen.
Sehe ich das richtig, dass ich mir dann die Längenangaben der Strings im File sparen kann? TReader z.B. hat ja die Funktion ReadString. Erkennt der Reader dann irgendwie, ob ein String zuende ist oder nicht?
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 17.07.05 14:06 
Write und readstring machen es intern genauso, sie speichern/lesen erst die länge des strings und dann den inhalt. Du selsbt brauchst dich nicht darum zu kümmern.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
Lemmingman2005 Threadstarter
Hält's aus hier
Beiträge: 12

Windows XP, Gentoo Linux 2005.0
Delphi 7.0 Enterprise
BeitragVerfasst: So 17.07.05 14:11 
Merci!
Es funzt perfekt mit TReader und TWriter. :D