2017-08-07 62 views
6

這個問題是非常基本的,因爲我在一個非常基礎的水平。我必須閱讀*.pam擴展名的文件內容。這並不常見,這是由特定程序生成的文件,它具有xx KB的固定大小。裏面有一些數字和值。Delphi讀取文件在特定地址

我需要閱讀這個文件,所以我打算使用TStreamReader。當然,我需要知道文件的結構,但我不知道。順便說我上面說的圖片是有用的信息表中的一個組成部分:

enter image description here

的含義是:一旦你打開的文件,去一個特定的地址,並獲得數據。例如,在0x30中,我可以找到有關'移動1當前PP'的數據。我的問題是:我如何跳轉到給定的地址?

procedure TForm1.Button1Click(Sender: TObject); 
var sw: TStreamReader; 
begin 

Memo1.Clear;  
sw := TStreamReader.Create('C:\aaa\myfile.pam', TEncoding.UTF8); 
try 

    sw.Position := 0; 

finally 
    sw.Free; 
end; 

我所看到的文件中,有一些像SeekPosition但似乎我不能使用它們。一般來說,我會使用

while not(sw.EndOfStream) do 
begin 
    //read... 
end; 

這從頭開始,它讀取seqence中的數據。我如何跳轉到特定地址並閱讀內容?我想我可以將這個十六進制地址傳遞給像Seek這樣的函數,所以我可以去一個特定的點。然後,我可以檢索數據。

+2

'TStreamReader'是用於讀取文本數據的助手類。你的文件不是文本,它是二進制文件。直接使用'TFileStream',然後你可以使用'Seek''''位置' –

回答

5

如果文件內容是二進制文件(與文本相反),請不要使用任何類型的文本編碼選項。

在以下示例中,我使用TFileStream來處理文件並讀取文件的選定部分。方法procedure ReadBuffer()具有重載,可以使用類型爲TBytes的非類型化緩衝區或緩衝區。如果請求的字節數不能被讀取,則會引發EReadError異常。

var 
    fn: TFileName; 
    fs: TFileStream; 
    b: byte; 
    bf: array[0..3] of word; 
    ReadResult: integer; 
begin 
    fn := 'c:\tmp\MyMagicalFile.pam'; 
    fs := TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite); 
    try 
    fs.Seek($28, soFromBeginning); // move to offset $28 in the file 
    fs.ReadBuffer(bf, 8);    // read 4 x 2 bytes into buffer (bf) 
             // fs.Position is at this point at $30 
    fs.ReadBuffer(b, 1);    // read one byte (at offset $30) into the buffer (b) 
    finally 
    fs.free; 
    end; 
    // use b and bf as needed 
end; 

如在上面的代碼中,通過使用Seek()方法跳轉到文件中的給定位置。讀取(或寫入)時,位置會自動更新。 SeekOptionssoFromBeginning,soFromCurrentsoFromEnd。 其他詳情請參閱System.Classes.TFileStream

+0

非常感謝,你已經保存了我的一天湯姆;)文件的「文檔」說數據存儲在小端,所以我猜測跳躍,因爲你做得很好。我對麼? –

+0

是的,這是正確的。並感謝你。 –

+0

你可能感興趣的[TBinaryReader](http://docwiki.embarcadero.com/Libraries/en/System.Classes.TBinaryReader)。 – Victoria