我需要使用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;
答案 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)
调用,而不是将每一行分别初始化为相同的宽度。