在Delphi中,使用SaveToStream将ClientDataSets和其他材料保存到文件中?

时间:2015-03-21 18:09:27

标签: delphi tclientdataset

我想使用SaveToStream来保存ClientDataSet ALONG WITH OTHER MATERIAL。这是一个简短的样本:

filename := ChangeFileExt(Application.ExeName, '.dat');
FS := TFileStream.Create(filename, fmCreate);

CDS.SaveToStream(FS);
ShowMessage('After save, position is ' + IntToStr(FS.Position));

{now write a longint}
L := 1234;
siz := SizeOf(L);
Write(L, siz);

FS.Free;

但是当我尝试使用LoadFromStream加载它时,我再次显示加载ClientDataSet后的位置,我看到该位置现在是最初保存clientdataset后的4个字节。似乎CDS.LoadFromStream只是向前推进并消耗它后面的任何东西。结果,当我尝试读取longint时,我收到文件结束错误。

仅仅在创建文件结束时使用CDS.SaveToStream是不够的,因为我真正想做的是将两个clientdatasets一个接一个地保存到文件中,加上其他材料

想法?感谢。

1 个答案:

答案 0 :(得分:0)

[注意,这个解决方案基本上加倍了(TLama的建议)“ReadDataPacket / WriteDataPacket”已在内部完成的工作。我会使用TLama的方法,即子类TClientDataSet来公开上述受保护的方法,并使用WriteSize参数。]

将数据集保存到临时流,然后将其复制到包含大小信息的目标流:

procedure InternalSaveToStream(AStream: TStream);
var
 ATempStream: TMemoryStream;
 ASize: Int64;
begin
 ATempStream := TMemoryStream.Create;

 // Save first dataset:
 DataSet1.SaveToStream(ATempStream, dfBinary);
 ASize := ATempStream.Size;
 AStream.WriteData(ASize);
 ATempStream.Position := 0;
 AStream.CopyFrom(ATempStream, ALength);
 ATempStream.Clear;

 // Save second dataset:
 DataSet2.SaveToStream(ATempStream, dfBinary);
 ASize := ATempStream.Size;
 AStream.WriteData(ASize);
 ATempStream.Position := 0;
 AStream.CopyFrom(ATempStream, ALength);
 ATempStream.Clear; 

 FreeAndNil(ATempStream);
end;

要回读,首先要读取大小,然后再将源的该部分复制到临时流并从中加载数据集:

procedure InternalLoadFromStream(AStream: TStream);
var
 ATempStream: TMemoryStream;
 ASize: Int64;
begin
 ATempStream := TMemoryStream.Create;

 // Load first datset:
 AStream.Read(ASize,SizeOf(ASize));
 ASize := ATempStream.Size;
 ATempStream.CopyFrom(AStream,ASize);
 ATempStream.Position := 0;
 DataSet1.LoadFromStream(ATempStream);

 //...etc.

end;