在Delphi中,使用SaveToStream将ClientDataSet和其他资料保存到文件中?
我想使用SaveToStream保存ClientDataSet和其他资料。以下是一个简短的示例:在Delphi中,使用SaveToStream将ClientDataSet和其他资料保存到文件中?,delphi,tclientdataset,Delphi,Tclientdataset,我想使用SaveToStream保存ClientDataSet和其他资料。以下是一个简短的示例: filename := ChangeFileExt(Application.ExeName, '.dat'); FS := TFileStream.Create(filename, fmCreate); CDS.SaveToStream(FS); ShowMessage('After save, position is ' + IntToStr(FS.Position)); {now write
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是不够的,因为我真正想做的是将两个ClientDataSet一个接一个地保存到文件中,再加上其他材料
想法?谢谢。[NB,这个解决方案实际上是将(特拉玛的建议)“ReadDataPacket/WriteDataPacket”在内部已经做的工作加倍。我将使用特拉玛的方法,即子类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;
ReadDataPacket
和WriteDataPacket
方法(即底层流读取器和写入器方法)具有布尔参数,允许数据集存储并读取要处理到流的数据大小。所以,我认为最简单的任务可能是为数据集创建一个子类,并填充(并使用)这个布尔参数?