線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1470
推到 Plurk!
推到 Facebook!

TStringList + TObject如何存取於檔案中

尚未結案
brianwung
一般會員


發表:18
回覆:22
積分:8
註冊:2002-06-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-04-06 00:30:37 IP:203.204.xxx.xxx 未訂閱
stringlist addobject後 用memory stream存起來, 卻只有存stringlist的strings 請問有其它方法可以一次就 把stringlist的object存在檔案中嗎? 謝謝
hagar
版主


發表:143
回覆:4056
積分:4445
註冊:2002-04-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-04-06 06:42:04 IP:202.39.xxx.xxx 未訂閱
運用 TReader/TWriter, 參考: http://groups.google.com.tw/groups?hl=zh-TW&lr=&ie=UTF-8&oe=UTF-8&selm=8F3DBD66Ectimmonslgrscom%40207.105.83.65&rnum=3
type
  TObj = class(TObject)
  public
    Int : integer;
    Bool : boolean;
    constructor Create(const AInt : integer; const ABool : boolean);
  end;    var
  StringList : TStringList;    const
  FFileName = 'c:\windows\temp\test.txt';    procedure PopulateStringList;
begin
  StringList := TStringList.Create;      with StringList do
  begin
    AddObject('Item 1', TObj.Create(6, true));
    AddObject('Item 2', TObj.Create(7, false));
    AddObject('Item 3', TObj.Create(8, true));
    AddObject('Item 4', TObj.Create(9, false));
    AddObject('Item 5', TObj.Create(10, true));
  end;
end;    procedure SaveStringListToFile;
var
  Writer : TWriter;
  FileStream : TFileStream;
  StringIndex : integer;
  Obj : TObj;
begin
  FileStream := nil;
  Writer := nil;      try
    // Create a file stream to write the stringlist to.
    FileStream := TFileStream.Create(FFileName, fmCreate);        // Create a writer object based on the file stream.
    // (TWriter's methods make it easy to read/write
    // date from/to a stream.)
    Writer := TWriter.Create(FileStream, 2048);        Writer.WriteListBegin;        // Save the number of items in the stringlist.
    Writer.WriteInteger(StringList.Count);        // Save each string and its associated object.
    for StringIndex := 0 to StringList.Count - 1 do
    begin
      // Write the string.
      Writer.WriteString(StringList[StringIndex]);          // Write the associated object's properties.          // Hint:  Write properties in alphabetical order in
      // both the load and save methods.  This ensures that
      // the data will be read in exactly the same order it
      // was written.
      Obj := TObj(StringList.Objects[StringIndex]);
      Writer.WriteBoolean(Obj.Bool);
      Writer.WriteInteger(Obj.Int);
    end; // for        Writer.WriteListEnd;
  finally
    Writer.Free;
    FileStream.Free;
  end; // try
end;    procedure ReadStringListFromFile;
var
  Reader : TReader;
  FileStream : TFileStream;
  StringIndex : integer;
  NumberOfStrings : integer;
  StringItem : string;
  ObjInt : integer;
  ObjBool : boolean;
begin
  FileStream := nil;
  Reader := nil;      try
    // Create a file stream to read the stringlist from.
    FileStream := TFileStream.Create(FFileName, fmOpenRead);        Reader := TReader.Create(FileStream, 2048);
    Reader.ReadListBegin;        // Read the number of items in the stringlist.
    NumberOfStrings := Reader.ReadInteger;        // Read each string and its associated object.
    for StringIndex := 1 to NumberOfStrings do
    begin
      // {
      // Read the string.
      StringItem := Reader.ReadString;          // Read the associated object's properties.
      ObjBool := Reader.ReadBoolean;
      ObjInt := Reader.ReadInteger;          // Create the stringlist entry.
      StringList.AddObject(StringItem, TObj.Create(ObjInt, ObjBool));
      // }          // You might be wondering - Why not just do this:          { StringList.AddObject(Reader.ReadString,
        TObj.Create(Reader.ReadInteger, Reader.ReadBoolean)); }          // and dispense with the intermediate variables (StringItem, etc.)?          // The problem is the order in which the parameters are executed.
      // For some reason, the above TReader methods are executed backwards
      // (i.e. ReadBoolean is executed first, then ReadInteger, then
      // ReadString).          // You can see this in action by using the debugger:          // 1.  Comment out the block of code between // { and // }.          // 2.  Uncomment the StringList.AddObject w/ the Read* methods.          // 3.  Set a breakpoint on that line.          // 4.  Run the program.  Press the buttons in order.          // 5.  When the program stops on the above line of code, open the
      //     VCL file Classes.pas and set breakpoints inside
      //     TReader.ReadBoolean and TReader.ReadString.          // 6.  Press F9 to continue running the program.          // Which breakpoint in TReader is hit first?  It should be 
ReadString,
      // but it's not.  ReadBoolean is executed first, which results in
      // an invalid property error since the next item in the file stream 
is
      // a string, not a boolean value.          // I don't know why this happens, since all Delphi
      // methods use the register calling convention (left-to-right) by
      // default.  Here it seems the parameters are being passed
      // right-to-left ?!?
    end; // for        Reader.ReadListEnd;
  finally
    Reader.Free;
    FileStream.Free;
  end; // try
end;
-- He just never quits. 發表人 - hagar 於 2004/04/06 06:43:53
系統時間:2024-05-16 22:58:06
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!