代码之家  ›  专栏  ›  技术社区  ›  RobertFrank Picarus

如何使用TFileStream将二维矩阵读入动态数组?

  •  2
  • RobertFrank Picarus  · 技术社区  · 16 年前

    我需要用delphi2010把一个文件中的一个大的(2000x2000)二进制数据矩阵读入一个动态数组中,直到运行时我才知道它的维数。

    我从来没有读过这样的原始数据,也不了解IEEE,所以我发布这个来看看我是否在正轨上。

     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位2的补码,我在想下面的代码。换成Int64和Int16应该是直截了当的。我怎么读IEEE?

    我走对了吗?对这段代码有什么建议,或者如何优雅地将其扩展到上述所有4种数据类型?由于我的后处理在读取这些数据后将是相同的,我想我将不得不复制到一个共同的格式矩阵完成后。

    我只需要四个过程(每个数据类型一个)就可以了,就像下面的一样,但是也许有一种优雅的方法可以使用RTTI或buffers,然后move(),这样所有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 回复  |  直到 16 年前
        1
  •  4
  •   Mason Wheeler    16 年前

    不,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 length参数传递给SetLength,而不仅仅是一个参数。所以用一个电话 SetLength(Matrix, NumberOfRows, NumberOfCols) 在循环外部,而不是将每行分别初始化为相同的宽度。