如何使用TFileStream将2D矩阵读入动态数组?

时间:2010-05-20 22:02:37

标签: delphi

我需要使用Delphi 2010将大型(2000x2000)二进制数据矩阵从文件读入动态数组。直到运行时我才知道维度。

我从来没有读过这样的原始数据,也不知道IEEE所以我发布这个是为了看看我是否正常。

我计划使用TFileStream一次读取一行。

我需要能够尽可能多地阅读这些格式:

 16-bit two's complement binary integer
 32-bit two's complement binary integer
 64-bit two's complement binary integer
 IEEE single precision floating-point

对于32位二进制补码,我想的是类似下面的代码。更改为Int64和Int16应该是直截了当的。我怎样才能阅读IEEE?

我是否在正确的轨道上?有关此代码的任何建议,或如何针对上述所有4种数据类型优雅地扩展它?由于我在阅读这些数据后的后处理方式是相同的,我想我必须在完成后将矩阵复制成通用格式。

我只有四个程序(每个数据类型一个)没有问题,如下所示,但也许有一种优雅的方式来使用RTTI或缓冲区然后移动(),以便相同的代码适用于所有4数据类型?

谢谢!

  type
    TRowData = array of Int32;

   procedure ReadMatrix;
   var
     Matrix: array of TRowData;
     NumberOfRows: Cardinal;
     NumberOfCols: Cardinal;
     CurRow: Integer;
   begin
     NumberOfRows := 20; // not known until run time
     NumberOfCols := 100; // not known until run time
     SetLength(Matrix, NumberOfRows);
     for CurRow := 0 to NumberOfRows do
       begin
         SetLength(Matrix[CurRow], NumberOfCols);
         FileStream.ReadBuffer(Matrix[CurRow], NumberOfCols * SizeOf(Int32)) );
       end;
   end;

1 个答案:

答案 0 :(得分:4)

不,AFAIK没有办法使用RTTI来设置多维数组。但是如果您使用的是Delphi 2010,那么您应该能够使用泛型,如下所示:

type
  TRowData<T> = array of T;

 procedure ReadMatrix<T>;
 var
   Matrix: array of TRowData<T>;
   NumberOfRows: Cardinal;
   NumberOfCols: Cardinal;
   CurRow: Integer;
 begin
   NumberOfRows := 20; // not known until run time
   NumberOfCols := 100; // not known until run time
   SetLength(Matrix, NumberOfRows, NumberOfCols);
   for CurRow := 0 to NumberOfRows do
     FileStream.ReadBuffer(Matrix[CurRow][0], NumberOfCols * SizeOf(T)) );
 end;

这必须在课堂上,Delphi 2010 doesn't support standalone procedures with generic types。完成此设置后,您可以致电TWhateverClass.ReadMatrix<integer>TWhateverClass.ReadMatrix<int64>TWhateverClass.ReadMatrix<single>,依此类推。

此外,如果您有一个具有X维度的多维数组,则可以将X长度参数传递给SetLength,而不仅仅是一个。因此,在循环外使用一次SetLength(Matrix, NumberOfRows, NumberOfCols)调用,而不是将每一行分别初始化为相同的宽度。