2010-05-20 84 views
2

我需要使用Delphi 2010從文件讀取一個大的(2000x2000)二進制數據矩陣到動態數組。我直到運行時才知道維數。如何使用TFileStream將2D矩陣讀入動態數組?

我從來沒有讀過像這樣的原始數據,也不知道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

如果在循環之前調用SetLength(Matrix,NumberOfRows,NumberOfCols),並且省略循環內的SetLength,性能將得到改善。 – 2010-05-20 22:14:41

+0

讀取浮點值將沒有什麼不同:只需將Int32替換爲正確的數據類型,即Single。與許多其他語言和環境一樣,Delphi使用IEEE進行浮點表示。 – 2010-05-20 22:17:54

回答

4

不,AFAIK沒有辦法使用RTTI來設置多維數組。但是,如果你正在使用德爾福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),而不是分別初始化每行到相同的寬度。

+1

絕對優雅,是泛型的一個很好的例子,梅森。謝謝!!! – RobertFrank 2010-05-20 22:28:40

+0

如果有人試圖這樣做,我發現ReadBuffer語句要求提供兩個下標而不是一個。否則,Readbuffer不會填充每行的前幾個元素。 正確的行顯示爲: FileStream.ReadBuffer(Matrix [CurRow] [0],NumberOfCols * SizeOf(T))); – RobertFrank 2010-05-21 12:45:31

+0

你說得對。謝謝。修復。 – 2010-05-21 13:26:33