Matlab 用fread、fwrite實現大文件讀寫


最近在分析一個35G的大數據文件,猛一看,是不是很嚇人啊,不過還好,師兄寫文件的格式非常規范,讀取數據來也就很方便了,主要是使用了讀寫文件的兩個函數fread和fwrite,下面用matlab簡單嘗試一下,對於這種文件讀取的低級函數,c和matlab功能都是差不多的。

先來看fwrite,最簡單的用法如下

%%

x = 1:15;

dataw = reshape(x, 5, 3);

disp(dataw)

%%

filename = 'test.bin';

hfile = fopen(filename, 'w');

fwrite(hfile, dataw, 'double');

fclose(hfile);

fwrite寫矩陣,是按列來寫的,即先寫第一列,再第二列,以此類推。如上面的代碼,x為

1     6    11

2     7    12

3     8    13

4     9    14

5    10    15

如果把數據全部讀出來,就是

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

稍復雜的寫法是,可以跳着寫,就是每個數據先跳幾個位置,然后再寫數據,如上面的5X3矩陣,如果想按行來寫,當然最簡單的方式是先轉置一下再寫,但如果數據量非常大,而且還在另一個文件里,總不能先都讀取進來,再轉置、寫,當然這只是一種特殊情況,但跳着寫在某些時候確實是好的解決方法,如下實現按行寫

%%

x = 1:15;

dataw = reshape(x, 5, 3);

disp(dataw)

len = 5;

count = 3;

%%

filename = 'test.bin';

hfile = fopen(filename, 'w');  

fwrite(hfile, zeros(count, 1), 'double'); % 先寫一行0,因為fwrite總是先跳再寫,對於第一行也要先跳,那就先在第一行補個零吧

for i = 1:count

    fseek(hfile, 8*i, 'bof'); % 常常要配合fseek使用 fseek(fid,offset,origin);

% double matlab 中是 'real*8' 表示64位共8字節的浮點數

%所以上面的fwrite(hifle,zeros(count,….) 寫入了24個字節的數據

%因為fwrite寫入數據后會把當前指針hfile移動到最后一個字節位置, 所以此時ftell(hfile)就為24

    fwrite(hfile, dataw(1:end, i), 'double', 8*(count-1)); % fwrite(fid,A,precision,skip)

%fwrite(hfile,dataw(1:end,1),…)這一行表示將dataw矩陣中的第一列數據1 2 3 4 5 每隔16個字節(因為這里用的double型,每個數據位占用了8字節)寫入一個數據

%因為fwrite()是先跳后寫入,即在寫入dataw中第一列的第一個數據值1之前hfile在當前指針所指字節數的位置向前跳8*(count-1)個字節,然后寫入這個數值1(這個1占用了8個字節,共64位),然后再跳8*(count-1)個字節,接着寫入數值2dataw的第一列第二個值),直到把這列數據寫完!然后繼續循環

    %dataw(1:end,i)表示取矩陣的第i列,可寫為dataw(:,i)

end

fclose(hfile);

hfile = fopen(filename, 'r');

datar = fread(hfile, 100, 'double')

fclose(hfile);

結果如下

     1     6    11

     2     7    12

     3     8    13

     4     9    14

     5    10    15

datar =

     0

     0

     0

     1

     6

    11

     2

     7

    12

     3

     8

    13

     4

     9

    14

     5

    10

    15

 

fwrite寫的文件再配合上fread讀,那真是天作之合了,35G的數據也是浮雲啊!

最簡單的讀取方式就是上面的

datar = fread(hfile, 100, 'double')

直接讀取100個數據。當然更靈活的是跳着讀,如下面的程序

%%

x = 1:15;

dataw = reshape(x, 5, 3);

disp(dataw)

%%

filename = 'test.bin';

hfile = fopen(filename, 'w');

fwrite(hfile, dataw, 'double');

fclose(hfile);

%% 跳着讀

ind = 2; % 讀第幾時刻的數據

len = 5; % 一次數據的長度

hfile = fopen(filename, 'r');

fseek(hfile, 8*(ind - 1), 'bof');

datar = fread(hfile, 3, 'double', 8*(len - 1)); % double為8個字節

fclose(hfile);

disp(datar)

結果如下

1     6    11

2     7    12

3     8    13

4     9    14

5    10    15

2

7

12

這意思就是,文件中存儲的數據為1到15,但如果我想讀取上面矩陣中的第一行,即1,6,11,那就可以跳着讀,但注意跳着讀時,第一個數據是不跳直接讀的,幫助里的說明是skips skip bytes after reading each value,這是和fwrite不同的地方,skips skip bytes before writing each value,所以上面fwrite跳着寫的時候要先補一下0,再跳着寫,方便一些。

 

源文檔 <http://blog.sina.com.cn/s/blog_6163bdeb0102dqtk.html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM