如何使用 TStream 填充整数矩阵

How to use TStream to fill a matrix of integers

我正在尝试读取 PGM 二进制文件 (http://netpbm.sourceforge.net/doc/pgm.html) 以填充基于 0 的二维整数矩阵(16 位灰度值)。

该文件可能有 50 兆,因此我试图在一次调用中填充缓冲区。

我以前从未对 Streams 做过任何事情,但是 Google 上 Delphi 流的结果可以追溯到 20 年前,是一团乱麻,我找不到自己的路。

我设法锁定了 Delphi(15 年来第一次!)而 运行 一些使用指针和缓冲区的代码(并且可能是基于我对过时方法的误解.)

这是我的伪代码,逐个整数地执行。有没有办法通过单个 Stream 调用来读取和填充矩阵? (假设文件是​​在同一台机器上创建的,所以byte-sex是一样的。)

    type 
      TMatrix: Array of Array of Integer;

    procedure ReadMatrix( const AFileName: String;
                          const AStartingByte: Integer;         
                          const AMaxRow: Integer;
                          const AMaxCol: Integer;
                          const AMatrix: TMatrix)
    begin
      SetLength(AMatrix, aMaxRow, aMaxCol);
      Open(AFileName);
      Seek(AStartingByte);
      for Row := 0 to aMaxCol do
        for Col := 0 to aMaxCol do
          AMatrix[Row, Col] := ReadWord
    end;

而且,不,这不是家庭作业! :-)

如前所述,您不能在一次操作中读取二维动态数组,因为它的内存是不连续的。但是每个一维子数组都可以被填充。

我还将数组元素类型更改为 16 位。如果你真的需要 Integer 的矩阵(它是 32 位),那么你必须读取 16 位数据并将元素一个一个地分配给 Integers

 type 
      TMatrix = Array of Array of Word;  

 procedure ReadMatrix( const AFileName: String;
                          const AStartingByte: Integer;         
                          const AMaxRow: Integer;
                          const AMaxCol: Integer;
                          const AMatrix: TMatrix)
var
  FS: TFileStream;
  Row: Integer;   
begin
   SetLength(AMatrix, aMaxRow, aMaxCol);
   FS := TFileStream.Create(AFileName, fmOpenRead);
   try
      FS.Position := AStartingByte;
      for Row := 0 to aMaxRow - 1 do
         FS.Read(AMatrix[Row, 0], SizeOf(Word) * aMaxCol);
   finally
      FS.Free;
   end;
end;