我想使用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一个接一个地保存到文件中,加上其他材料
想法?感谢。
答案 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;