我有一个数据结构如下:TPicInfo = record
  PicName  : string;
  StorePic : TGraphic;
end;
我现在需要将TPicInfo的实例数据存入一个名为PicList.dat的文件中。
请各位写出读写方法,谢谢。

解决方案 »

  1.   

    //转贴大富翁历险数据库上的一篇讨论
    问题的标题是: 记录文件中如何正确保存string类型的"大"数据(超过256个字符)? (50分 )
     
    来自:wind98 时间:2001-10-17 14:24:00 ID:677738 记录文件中如何正确保存string类型的"大"数据(超过256个字符)?
    type
      TMyRec = Record
         a:string[10];
         b:string;//要保存的数据比较大,所以这里用string而不用string[255];
      end;//保存成文件:
    procedure SaveRec(sFN, sStr1, sStr2: string);
    var
      aRec              : array of TMyRec;
    var
      FStr              : TMemoryStream;
      i                 : longint;
    begin
      {获得文件中的记录,如果文件不存在则为空}
      GetAllRec(sFN);
      {获得得文件中的记录数,如果文件不存在则为0}
      i := GetRecNums(sFN);
      SetLength(aRec, i + 1);
      with aRec[i] do
        begin
          a := sStr1;
          b := sStr2;
        end;
      FStr := TMemoryStream.Create;
      {记录数}
      i := length(aRec);
      {保存记录数}
      FStr.Write(i, sizeof(i));
      {保存数据}
      for i := 0 to high(aRec) do
        FStr.Write(aRec[i], sizeof(aRec[i])); //这一句有问题,无法正确保存数据,我想应该是无法确定其大小的原因
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//因为如果将b:string;改为b:string[255];则可以正确保存
      FStr.SaveToFile(sFN);
      FStr.Free;
    end;  
    end; 
    来自:commons_sheng 时间:2001-10-17 14:30:00 ID:677750 用AnsiString吧 
    来自:eric.youbin 时间:2001-10-17 14:34:00 ID:677762 这个问题可不可以这么解
    var
      filecontent : Tstrings;
    procedure SaveRec(sFN,sStr1, sStr2: string);
    begin
      if filecontent= nil then
      filecontent := Tstringlist.create;
      //添加对stringlist的操作
     filecontent.savetofile(sfn);
      一切ok!
    end; 
    来自:教父 时间:2001-10-17 15:16:00 ID:677840 to eric.youbin:你这种方法好象没有办法处理结构文件,只能处理纯文本文件。
    这段时间我一直都在处理这种结构文件,我觉得象这种变长的字符串(String)不应该放
    在记录中,我就是把他们分开处理的,也就是说有两个文件,一个是索引,一个存放内容。 
    来自:wind98 时间:2001-10-17 15:16:00 ID:677839 to commons_sheng:
    没用的,这个不是string或ansistring的原因,记录中的string类型可以保存很多的字符(超过256),
    我们可以通过单步运行或用ShowMessage();来查看,就是保存的时候会出错,总是把不定长度的字段
    (如b:string)给保存错误了,而对于定长的(如:a:string[10])就可以很好地保存。
    to eric.youbin:
    我不想用TStrings来处理,因为我上所举的只有两个"字段"而已,而实际上有很多个,
    而且保存后还要读出来,一个"字段"一个"字段"地读,用TStrings有很多方面不好处理,
    我也不想用数据库,所以只好用record来处理了。
    大家继续...
     
    来自:wind98 时间:2001-10-17 15:20:00 ID:677848 to 教父:
    能具体说说吗?最好能举例说明![8D] 
    来自:教父 时间:2001-10-17 18:22:00 ID:678197 比如你的记录可以这样定义:
    MyRec=record
      a:String[10];
      StartPos,
      Size:longint;
      end;
    然后再同时打开两个文件,记下内容文件的位置,写入StartPos,将内容的长度写入
    Size,将内容写入内容文件,将结构写入索引文件。
     
    来自:wind98 时间:2001-10-18 11:33:00 ID:679137 to 教父:
      你的方法也是可行的,不过,你要分两个文件来操作,无形中也给操作带来了不便。
      昨天请教了一位同事,他提供了一种想法,就是用TStringStream来保存数据,然后
      把TStringStream数据流倒入TMemoStream中,然后用TMemoStream保存成文件:)
      我试了,可以!呵呵...代码如下:
    const 
      sJG = '##';
    procedure TForm1.SaveRec(sFN: string);
    {保存记录}
    var
      FStr              : Tstringstream;
      FMemo             : TMemoryStream;
      i                 : longint;
      ph                : string;
    begin
      FStr := TstringStream.Create(ph);
      for i := 0 to high(aRec) do
        begin
          FStr.WriteString(a+sJG); //每个"字段"之间用##隔开,具体用什么隔开可以自已定义
          FStr.WriteString(b+sJG);
        end;
      FStr.Position := 0;
      FMemo := TMemoryStream.Create;
      FMemo.CopyFrom(FStr, FStr.Size); //倒入数据流到FMemo
      FMemo.SaveToFile(sFN);  //保存文件
      FStr.Free;
    end;procedure TForm1.GetAllRec(sFN: string);
    {读:获得记录内容}
    var
      slTmp1, slTmp2    : TStrings;
      i, j, k           : longint;
    begin
      slTmp1 := TStringList.Create;
      slTmp2 := TStringList.Create;
      if not FileExists(sFN) then Exit; //文件不存在退出
      slTmp1.LoadFromFile(sFN);
      CheckSite(slTmp1.Text, sJG, slTmp2); //把字符串以sJG为分隔符分开,保存在slTmp2中
      SetLength(aRec, 1);
      j := 0; //字段数记数器
      k := 0; //记录数记数器
      for i := 0 to slTmp2.Count - 1 do
        begin
          case j of
            0: aRec[k].a := slTmp2[i];
            1: aRec[k].b := slTmp2[i];
          end;
          if j >= high(aRec) then //到最后一个字段
            begin
              inc(k);  //记录数加1
              j := 0; //字段数清0,从第一个字段再开始
              if i < slTmp2.Count - 1 then //slTmp2中还有数据
                SetLength(aRec, high(aRec) + 2);  //aRec添加一条记录
            end
          else inc(j); //下一个字段
        end;
      slTmp1.Free;
      slTmp2.Free;
    end;function TForm1.CheckSite(const Str, Ch: string; var Mystring: TStrings)
      : boolean;
    {字符串Str以Ch分隔成几段小字符串,该函数是将这些小字符串提取出来并保存在MyString中}
    var
      sit, n            : integer;
      S                 : string;
    begin
      Result := True;
      MyString.Clear;
      S := Str;
      n := Length(Ch);
      while True do
        begin
          if Pos(Ch, S) = 0 then
            begin
              MyString.Add(S);
              Break;
            end;
          sit := Pos(Ch, S);
          MyString.Add(Copy(S, 1, sit - 1));
          S := Trim(Copy(S, sit + n, Length(S)));
        end;
      if MyString.Count < 2 then Result := False;
    end;以上代码在Delphi5+Wind2000下调试运行通过。
     
    来自:wind98 时间:2001-10-19 14:03:00 ID:681218 多人接受答案了。 
    来自:教父 时间:2001-10-19 14:22:00 ID:681249 这样做是可以实现,可是这样写到一个文件中,好象不太容易实现如:检索、修改、删除
    等操作。其实你看看DBF的结构,它也是把Memo部分单独分出来的。
     
    来自:wind98 时间:2001-10-19 23:36:00 ID:682292 to 教父:
    我在GetAllRec(sFN: string);函数中其实已经把数据读到aRec中去了,检索、修改、删除
    等操作直接对aRec操作就行了。