Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Delphi中,使用SaveToStream将ClientDataSet和其他资料保存到文件中?_Delphi_Tclientdataset - Fatal编程技术网

在Delphi中,使用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

我想使用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 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
方法(即底层流读取器和写入器方法)具有布尔参数,允许数据集存储并读取要处理到流的数据大小。所以,我认为最简单的任务可能是为数据集创建一个子类,并填充(并使用)这个布尔参数?