如何使用TFileStream将2D矩阵读入动态数组? [英] How to use a TFileStream to read 2D matrices into dynamic array?

查看:66
本文介绍了如何使用TFileStream将2D矩阵读入动态数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to read a large (2000x2000) matrix of binary data from a file into a dynamic array with Delphi 2010. I don't know the dimensions until run-time.

我从来没有像这样读取过原始数据,也不知道IEEE,所以我将其发布以查看我是否在轨道上。

I've never read raw data like this, and don't know IEEE so I'm posting this to see if I'm on track.

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

I plan to use a TFileStream to read one row at a time.

我需要能够读取尽可能多的可能的格式如下:

I need to be able to read as many of these formats as possible:

 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?

For 32-bit two's complement, I'm thinking something like the code below. Changing to Int64 and Int16 should be straight forward. How can I read the IEEE?

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

Am I on the right track? Any suggestions on this code, or how to elegantly extend it for all 4 data types above? Since my post-processing will be the same after reading this data, I guess I'll have to copy the matrix into a common format when done.

我只有四个过程(每个数据类型一个),就像下面的过程一样,但没有问题,但是也许有一种优雅的方法来使用RTTI或缓冲区然后移动( ),这样相同的代码就可以用于所有4种数据类型?

I have no problem just having four procedures (one for each data type) like the one below, but perhaps there's an elegant way to use RTTI or buffers and then move()'s so that the same code works for all 4 datatypes?

谢谢!

  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;


推荐答案

不,AFAIK无法使用RTTI进行设置多维数组。但是,如果您使用的是Delphi 2010,则应该能够使用泛型,例如:

No, AFAIK there's no way to use RTTI to set up multidimensional arrays. But if you're using Delphi 2010, you should be able to use generics, like so:

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不支持具有泛型类型的独立过程。完成此设置后,可以调用 TWhateverClass.ReadMatrix< integer> TWhateverClass.ReadMatrix< int64> TWhateverClass.ReadMatrix< single> ,依此类推。

This will have to be in a class, though, as Delphi 2010 doesn't support standalone procedures with generic types. Once you've got this set up, you can call TWhateverClass.ReadMatrix<integer>, TWhateverClass.ReadMatrix<int64>, TWhateverClass.ReadMatrix<single>, and so on.

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

Also, if you have a multidimensional array with X dimensions, you can pass X length parameters to SetLength, not just one. So use one call to SetLength(Matrix, NumberOfRows, NumberOfCols) outside the loop, instead of initializing each row separately to the same width.

这篇关于如何使用TFileStream将2D矩阵读入动态数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆