2014-01-06 52 views
6

我決定使用memmapfile,因爲我的數據(通常是30Gb到60Gb)太大而不適合計算機的內存。MATLAB中的存儲器映射文件?

我的數據文件由兩列數據組成,這兩列數據對應於兩個傳感器的輸出,我有.bin和.txt兩種格式。

m=memmapfile('G:\E-Stress Research\Data\2013-12-18\LD101_3\EPS/LD101_3.bin','format','int32') 
m.data(1) 

我用上面的代碼存儲器映射我的數據給一個變量「M」,但我不知道用什麼樣的數據格式(INT8' ,‘INT16’,‘INT32’,‘Int64的’,」 uint8','uint16','uint32','uint64','單'和'雙')。事實上,我嘗試了MATLAB支持的所有數據格式,但是當我使用m.data(索引號)時,我從來沒有得到一對數字(2列數據),這也是我的預期,數字也會根據我使用的格式不同而不同。

如果有人有memmapfile的經驗,請幫助我。

Here是一些規模較小的版本,我的數據文件,這樣的人能理解我的數據是如何構成的:

歡呼 詹姆斯

+0

假設你有一個普通的二進制文件,沒有結構。所有的數據都是簡單的寫成一行,類似於'X(:)'將矩陣轉換爲矢量。你有任何信息如何寫入二進制文件?如果沒有,嘗試創建一個小例子.txt和.bin文件並上傳它們。 – Daniel

+0

看起來,使用「格式」選項可以指定「陣列形狀」。 –

+0

@DanielR我不知道如何編寫二進制文件,但我創建了一些相對較小的文件並上傳它們: https://www.dropbox.com/sh/rzut4zbrert9fm0/q9SiZYmrdG –

回答

5

memmapfile設計用於讀取二進制文件,這就是爲什麼你有麻煩您文本文件。那裏的數據是字符,所以你必須把它們看作字符,然後把它們解析成數字。更多關於下面的內容。

二進制文件似乎不僅包含以二進制格式寫入的浮點值流。我也在文件中看到標識符(字符串)和其他內容。您唯一希望閱讀的是聯繫創建二進制文件的設備的製造商,並詢問他們如何閱讀這些文件。可能會有一個SDK,或者至少是格式的描述。您可能想要考慮這一點,因爲文本文件中的浮點數可能會被截斷,即與直接讀取浮點數的二進制表示形式相比,您已經失去了精度。

好吧,那麼如何用memmapfile來讀取你的文件呢? This post提供了一些提示。

所以首先我們打開你的文件'uint8'(注意沒有'char'的選擇,因此作爲一種解決方法,我們讀取文件的內容轉換成大小相同的數據類型):

m = memmapfile('RTL5_57.txt','Format','uint8'); % uint8 is default, you could leave that off 

我們可以渲染通過鑄造它作爲UINT8爲字符讀取的數據爲char:

c = char(m.Data(1:19)).' % read the first three lines. NB: transpose just for getting nice output, don't use it in your code 
c = 
    0.398516 0.063440 
    0.399611 0.063284 
    0.398985 0.061253 

正如在文件中的每一行具有相同的長度(2 * 8個字符的數字,1片和2個字符爲換行= 19個字符),我們可以讀取N行該文件通過讀取N*19值。所以m.Data(1:19)可以讓你的第一行,m.Data(20:38),第二行,和m.Data(20:57)第二和第三行。儘可能多地閱讀你想要的內容。

那麼我們就必須讀入的數據解析成浮點數:

f = sscanf(c,'%f') 
f = 
    0.3985 
    0.0634 
    0.3996 
    0.0633 
    0.3990 
    0.0613 

所有現在剩下的就是將它們重新塑造成你的兩種欄格式

d = reshape(f,2,[]).' 
d = 
    0.3985 0.0634 
    0.3996 0.0633 
    0.3990 0.0613 

更容易方式比使用memmapfile: 你不需要使用memmapfile來解決你的問題,我認爲它使事情變得更加複雜。你可以簡單地使用fopen其次fread

fid = fopen('RTL5_57.txt'); 
c = fread(fid,Nlines*19,'*char'); 
% now sscanf and reshape as above 
% NB: one can read the values the text file directly with f = fscanf(fid,'%f',Nlines*19). 
% However, in testing, I have found calling fread followed by sscanf to be faster 
% which will make a significant difference when reading such large files. 

使用這個,你可以一次讀取Nlines對值,對它們進行處理,只是再次調用fread讀取下一個Nlinesfread會記住它在文件中的位置(與fscanf一樣),因此只需使用相同的呼叫即可獲取下一行。因此,它很容易編寫一個循環來處理整個文件,如果您位於文件末尾,則使用feof(fid)進行測試。

建議更簡單的方法here:使用textscan。稍微調整自己的示例代碼:

Nlines = 10000; 

% describe the format of the data 
% for more information, see the textscan reference page 
format = '%f\t%f'; 

fid = fopen('RTL5_57.txt'); 

while ~feof(fid) 
    C = textscan(fid, format, Nlines, 'CollectOutput', true); 
    d = C{1}; % immediately clear C at this point if you need the memory! 
    % process d 
end 

fclose(fid); 

注意卻又使fread其次sscanf將是最快的。但請注意,只要文本文件中有一行與您的格式不完全匹配,fread方法就會死亡。 textscan另一方面原諒空白的變化,從而更強大。

+0

感謝你的回答,它非常全面和有用。 –