【问题标题】:Reading from TStream into a dynamic array从 Stream 读入动态数组
【发布时间】:2017-04-28 07:29:41
【问题描述】:

德尔福 10.1 柏林。我有一个动态的记录数组。我想从 TStream 读取 N 条记录到该数组中。我想我需要打电话给ReadBuffer,但是第一个参数应该是什么样的? @MyArray 不起作用。

【问题讨论】:

    标签: delphi pascal


    【解决方案1】:

    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;
    

    【讨论】:

    • 如果是第一个代码段,需要检查 N=0。第二个没问题。
    • @MarcovandeVoort 这就是为什么我通常使用Pointer(MyArray)^ 语法,然后代码不必检查N=0,因为nil^ 可以安全地传递给var参数(实际上是将var参数设置为nil值的唯一方法),编译器为其生成正确的代码
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 2022-01-05
    • 2018-07-13
    • 2018-08-25
    相关资源
    最近更新 更多