【发布时间】:2017-04-28 07:29:41
【问题描述】:
德尔福 10.1 柏林。我有一个动态的记录数组。我想从 TStream 读取 N 条记录到该数组中。我想我需要打电话给ReadBuffer,但是第一个参数应该是什么样的? @MyArray 不起作用。
【问题讨论】:
德尔福 10.1 柏林。我有一个动态的记录数组。我想从 TStream 读取 N 条记录到该数组中。我想我需要打电话给ReadBuffer,但是第一个参数应该是什么样的? @MyArray 不起作用。
【问题讨论】:
TStream.Read() 和TStream.ReadBuffer() 将无类型的var 作为输入,这意味着您需要传入一个实际变量供他们访问。
作为动态数组的变量本身只是指向第一个数组元素的指针,实际的数组存储在内存中的其他位置。所以你不能将动态数组变量本身传递给Read/Buffer()。要传递的正确“变量”是第一个数组元素,因此请使用MyArray[0] 或Pointer(MyArray)^ 语法取消引用数组指针。
无论哪种方式,将记录从流中直接读取到数组中可能会或可能不会起作用,具体取决于您的记录类型的实际声明方式。
如果记录只包含 POD 类型,并且它的数据对齐方式与流数据的对齐方式相匹配,这将正常工作:
SetLength(MyArray, N);
if (N > 0) then
Stream.ReadBuffer(MyArray[0], N * SizeOf(MyRecord));
或者:
SetLength(MyArray, N);
Stream.ReadBuffer(Pointer(MyArray)^, N * SizeOf(MyRecord));
否则,您必须从流中单独读取每条记录,根据需要反序列化任何非 POD 类型,然后再将其复制到您的数组中:
var
Rec: MyRecord;
SetLength(MyArray, N);
for I := 0 to N-1 do
begin
// read individual members of Rec as needed...
Stream.ReadBuffer(Rec.SomeMember, SizeOf(Rec.SomeMember));
...
MyArray[I] := Rec;
end;
【讨论】:
Pointer(MyArray)^ 语法,然后代码不必检查N=0,因为nil^ 可以安全地传递给var参数(实际上是将var参数设置为nil值的唯一方法),编译器为其生成正确的代码