最近在分析一個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)個字節,接着寫入數值2(dataw的第一列第二個值),直到把這列數據寫完!然后繼續循環
%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,再跳着寫,方便一些。
