2017-06-01 146 views
1

在使用Win10 x64的筆記本電腦上,我使用了一種軟件,它將直方圖數據保存爲擴展名爲「.dat」的文件,並試圖打開它Win7 x64。MATLAB讀取二進制文件(十六進制)的內容,知道格式

在軟件文檔中,文件具有以下格式:

  1. 字節0到7是用於說明一個數字(上限圖的)
  2. 字節8到15是一個64位浮點描述一個數字(底部結合圖的)
  3. 字節16到19 64位浮點是一個無符號的32位整數設置爲0或1
  4. 字節20至23是一個無符號的32位整數設定爲0或1
  5. 字節24至27是一個無符號的32位整數設置成圖的寬度,以像素
  6. 字節28至31是一個無符號的32位整數設置成圖的高度,以像素
  7. 字節32至給定寬度和高度,800031對圖中每個點都有一個無符號的32位整數。 (因此它的4×寬×高= 800 000)

現在,如果我打開該文件用十六進制編輯,我可以看到對應於上述編號點這些值:

  1. '11 EA 2D 81 99 97 71 3D'
  2. '49 AF BC 9A F2 D7 7A 3E'
  3. '01 00 00 00'
  4. '00 00 00 00'
  5. 'F4 01 00 00'
  6. '90 01 00 00'
  7. 文件

從我所看到的,望着值3,並且知道應該是1或0,我可以看到,它實際上應'00 00 00 01'的其餘部分。在網上閱讀一些信息,我認爲這是'小端'。

在Matlab中,在我的Win7筆記本電腦上寫下以下內容,[cinfo, maxsize, ordering] = computer,我得到答案'L'。而在Matlab中的字符編碼是'windows-1252'。

測試使用各種工具所產生的值在網上我有以下幾點:

  • 使用http://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html爲1 和輸入字節爲十六進制,小端(所以, 的3D719799812DEA11的價值,而不是11EA2D819997713D )我得到 1.000e-12的結果。
  • 對於2.使用相同的url(因此,3D719799812DEA11的值代替 的11EA2D819997713D),我得到了1.0001e-7的結果。
  • 使用相同的url來獲取值小的,然後輸入 它將一個將unsigned int轉換爲二進制的站點,另一個 將二進制轉換爲小數,爲3.,4.,5。和6,我得到了 的值分別爲1,0,500和400。

這意味着,對於上述編號點的值是:

  1. 1E-12
  2. 1E-7
  3. 500(寬度,以像素爲單位)
  4. 400(高度,以像素爲單位)
  5. 4 * 500 * 400 = 8 00 000,所以它看起來是正確的。

所以,我知道我應該如果我嘗試在Matlab中打開文件。 這是我做過什麼至今:

name = 'histogram.dat'; 
fid = fopen(name,'r'); 
v = fread(fid); 

這爲v作爲800032x1雙。如果我打開v矢量I看到以下內容:

  • 列1到7(爲1):17; 234; 45; 129; 153; 151; 113]
  • 柱8至15(對於2):[61; 73; 175; 188; 154; 242; 215; 122]
  • 第16至19列(對於3):[62; 1; 0; 0]
  • 第20列至23(for 4.):[0; 0; 0; 0]
  • 第24至27列(對於5.):[0; 244; 1; 0]
  • 第28列至第31列:[0; 144; 1; 0]
  • 列32到8000032(爲7):其餘

接下來,我刪除了一切,然後我試圖閱讀下列方式二進制文件:

name = 'histogram.dat'; 
fid = fopen(name,'r'); 
c1 = fread(fid,8,'float64'); 
c2 = fread(fid,8,'float64'); 
c3 = fread(fid,4,'uint32'); 
c4 = fread(fid,4,'uint32'); 
c5 = fread(fid,4,'uint32'); 
c6 = fread(fid,4,'uint32'); 

現在我得到的東西完全不同。

c1 = [1.00e-12; 1.00e-07; 4.90e-324; 8.48e-312; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314 ]; 
c2 = [-1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314; -1.06e-314]; 
c3 to c6 = [2.1475e09; 2.1475e09; 2.1475e09; 2.1475e09]; 

因此,它似乎沒有達到預期效果。我如何在Matlab中打開該文件,並具有與我期望的相同的值?而且,我怎樣才能打開從31到最後的字節呢?我想我讀到每個4字節到最後,並獲得價值?另外,如果我得到每個向量的HEX值,並且我做了一個hex2num(前兩個,float64s)或一個hex2dec(對於下一個,uint32s),我會得到正確的結果。我還應該首先使用hex2numhex2dec二進制數字嗎?

另一種可能性是在普通的十六進制編輯器中打開該文件,獲取在Matlab中導入的大矢量,將字節順序與swapbyes交換,然後執行hex2num/dec。然後我會得到正確的值。

+0

[fo筆](https://www.mathworks.com/help/matlab/ref/fopen.html)有一個確定字節順序的選項。 – rahnema1

+0

謝謝你的回答!沒有必要去玩Endian,因爲它是一樣的左端。在兩臺機器上和Matlab上。嘗試使用或不使用參數的代碼,在fread或fopen上。 –

+0

歡迎來到SO!你不需要用答案編輯你的問題。如果您認爲答案對未來的用戶有價值,您可以用簡短的解釋來回答您自己的問題。如果你認爲答案只是一個錯字或簡單的錯誤,那麼你可以刪除這個問題。碰巧,湯姆剛纔在某種情況下給出了同樣的答案,所以考慮接受他的答案。我相應地回滾了你的編輯。 – Wolfie

回答

1

fread的第二個參數是要讀取的元素的數量,而不是字節數。它將根據您指定的數據類型調整字節數。因此,例如,在單個float64讀c1你真正想要

c1 = fread(fid,1,'float64'); 

您需要相應地調整其他值。要將其餘數據讀入到文件末尾,請用Inf替換第二個參數。

無需轉換爲或來自十六進制值;十六進制值就是關於如何在屏幕上顯示值。

+0

非常感謝! –

0

此外,您還可以讀取字節向量整個數據與

bytevec = fread(fid,inf,'uint8'); 

然後,您可以手動將其索引安排bytevec元素(或使用reshape),並調用

value = cast(bytevec(i1:i2), type); 

,然後再轉換它默認的matlab雙類型沒有改變數據:

double_value = typecast(value,'double');