请假设我有这个二叉树结构:
Type
TPMyTree = ^TMyTree;
TMyTree = Record
ID:Integer;
FullName:String[50];//<-------- fixed
addrs:String[50] // <----------- fixed
LeftT:TPMyTree;
RightT:TPMyTree;
end;
我如何从Stream中保存并加载它?
答案 0 :(得分:1)
使用流时,最复杂的问题是处理可变长度数据。在您的情况下,这是FullName
和addrs
,因为这些字段属于String
类型。最简单的解决方案是使用Delphi的流读取器和编写器帮助程序类TReader
和TWriter
,因为它们提供了使用字符串的简单方法。另一方面,最明显的解决方案是以递归方式将树写入流中,一次一个节点。
警告,用浏览器窗口编写的代码:
// This will save one node to the stream, using the TWriter helper. Takes
// care of potential NIL's.
procedure SaveBinaryTreeToStreamWriter(RootNode: TPMyTree; W: TWriter);
begin
if Assigned(RootNode) then
begin
W.WriteBoolean(True);
W.WriteInteger(RootNode^.ID);
W.WriteString(RootNode^.FullName);
W.WriteString(RootNode^.addres);
SaveBinaryTreeToStreamWriter(RootNode^.LeftT, W);
SaveBinaryTreeToStreamWriter(RootNode^.RightT, W);
end
else
W.WriteBoolean(False);
end;
// This will read one NODE from the stream, using the TReader helper.
// Uses the boolean "nil" marker saved by the writing routine to also
// return "nil" if needed.
function ReadBinaryTreeNodeFromReader(R: TReader):TPMyTree;
begin
if R.ReadBoolean then
begin
Result := AllocMem(SizeOf(TMyTree));
Result^.ID := R.ReadInteger;
Result^.FullName := R.ReadString;
Result^.addres := R.ReadString;
Result^.LeftT := ReadBinaryTreeNodeFromReader(R);
Result^.RightT := ReadBinaryTreeNodeFromReader(R);
end
else
Result := nil;
end;
// This simply creates the TWriter and then starts the recursive process of
// writing the tree to stream.
procedure SaveBinaryTreeToStream(RootNode: TPMyTree; Stream: TStream);
var W:TWriter;
begin
W := TWriter.Create(Stream, 128);
try
SaveBinaryTreeToStreamWriter(RootNode, W);
finally W.Free;
end;
end;
// This simply creates the TReader and then starts the recursive process of
// reading the tree one node at a time:
function ReadFromStream(Stream:TStream):TPMyTree;
var R: TReader;
begin
R := TReader.Create(Stream, 128);
try
Result := ReadBinaryTreeNodeFromReader(R);
finally R.Free;
end;
end;