在編寫一個程式時,經常需要從外部讀入資料,或者将程式運作的結果儲存為檔案。MATLAB使用多種格式打開和儲存資料。本章将要介紹 MATLAB中檔案的讀寫和資料的導入導出。
13.1 資料基本操作
本節介紹基本的資料操作,包括工作區的儲存、導入和檔案打開。
13.1.1 檔案的存儲
MATLAB支援工作區的儲存。使用者可以将工作區或工作區中的變量以檔案的形式儲存,以備在需要時再次導入。儲存工作區可以通過菜單進行,也可以通過指令視窗進行。
1. 儲存整個工作區
選擇File菜單中的Save Workspace As…指令,或者單擊工作區浏覽器工具欄中的Save,可以将工作區中的變量儲存為MAT檔案。
2. 儲存工作區中的變量
在工作區浏覽器中,右擊需要儲存的變量名,選擇Save As…,将該變量儲存為MAT檔案。
3. 利用save指令儲存
該指令可以儲存工作區,或工作區中任何指定檔案。該指令的調用格式如下:
● save:将工作區中的所有變量儲存在目前工作區中的檔案中,檔案名為 matlab.mat,MAT檔案可以通過load函數再次導入工作區,MAT函數可以被不同的機器導入,甚至可以通過其他的程式調用。
● save(\'filename\'):将工作區中的所有變量儲存為檔案,檔案名由filename指定。如果filename中包含路徑,則将檔案儲存在相應目錄下,否則預設路徑為目前路徑。
● save(\'filename\', \'var1\', \'var2\', ...):儲存指定的變量在 filename 指定的檔案中。
● save(\'filename\', \'-struct\', \'s\'):儲存結構體s中全部域作為單獨的變量。
● save(\'filename\', \'-struct\', \'s\', \'f1\', \'f2\', ...):儲存結構體s中的指定變量。
● save(\'-regexp\', expr1, expr2, ...):通過正規表達式指定待儲存的變量需滿足的條件。
● save(\'..., \'format\'),指定儲存檔案的格式,格式可以為MAT檔案、ASCII檔案等。
13.1.2 資料導入
MATLAB中導入資料通常由函數load實作,該函數的用法如下:
● load:如果matlab.mat檔案存在,導入matlab.mat中的所有變量,如果不存在,則傳回error。
● load filename:将filename中的全部變量導入到工作區中。
● load filename X Y Z ...:将filename中的變量X、Y、Z等導入到工作區中,如果是MAT檔案,在指定變量時可以使用通配符“*”。
● load filename -regexp expr1 expr2 ...:通過正規表達式指定需要導入的變量。
● load -ascii filename:無論輸入檔案名是否包含有擴充名,将其以ASCII格式導入;如果指定的檔案不是數字文本,則傳回error。
● load -mat filename:無論輸入檔案名是否包含有擴充名,将其以mat格式導入;如果指定的檔案不是MAT檔案,則傳回error。
例13-1 将檔案matlab.map中的變量導入到工作區中。
首先應用指令whos –file檢視該檔案中的内容:
>> whos -file matlab.mat
Name Size Bytes Class
A 2x3 48 double array
I_q 415x552x3 687240 uint8 array
ans 1x3 24 double array
num_of_cluster 1x1 8 double array
Grand total is 687250 elements using 687320 bytes
将該檔案中的變量導入到工作區中:
>> load matlab.mat
該指令執行後,可以在工作區浏覽器中看見這些變量,如圖13-1所示。
圖13-1 導入變量後的工作區視圖
接下來使用者可以通路這些變量。
>> num_of_cluster
num_of_cluster =
3
MATLAB中,另一個導入資料的常用函數為importdata,該函數的用法如下:
● importdata(\'filename\'),将filename中的資料導入到工作區中;
● A = importdata(\'filename\'),将filename中的資料導入到工作區中,并儲存為變量A;
● importdata(\'filename\',\'delimiter\'),将filename中的資料導入到工作區中,以delimiter指定的符号作為分隔符;
例13-2 從檔案中導入資料。
>> imported_data = importdata(\'matlab.mat\')
imported_data =
ans: [1.1813 1.0928 1.6534]
A: [2x3 double]
I_q: [415x552x3 uint8]
num_of_cluster: 3
與load函數不同,importdata将檔案中的資料以結構體的方式導入到工作區中。
13.1.3 檔案的打開
MATLAB中可以使用open指令打開各種格式的檔案,MATLAB自動根據檔案的擴充名選擇相應的編輯器。
需要注意的是open(\'filename.mat\')和load(\'filename.mat\')的不同,前者将filename.mat以結構體的方式打開在工作區中,後者将檔案中的變量導入到工作區中,如果需要通路其中的内容,需要以不同的格式進行。
例13-3 open與load的比較。
>> clear
>> A = magic(3);
>> B = rand(3);
>> save
Saving to: matlab.mat
>> clear
>> load(\'matlab.mat\')
>> A
A =
8 1 6
3 5 7
4 9 2
>> B
B =
0.9501 0.4860 0.4565
0.2311 0.8913 0.0185
0.6068 0.7621 0.8214
>> clear
>> open(\'matlab.mat\')
ans =
A: [3x3 double]
B: [3x3 double]
>> struc1=ans;
>> struc1.A
ans =
8 1 6
3 5 7
4 9 2
>> struc1.B
ans =
0.9501 0.4860 0.4565
0.2311 0.8913 0.0185
0.6068 0.7621 0.8214
13.2 文本檔案的讀寫
在上一節中介紹的函數和指令主要用于讀寫mat檔案,而在應用中,需要讀寫更多格式的檔案,如文本檔案、word檔案、xml檔案、xls檔案、圖像檔案和音視訊檔案等。本節介紹文本檔案(txt)的讀寫。其他檔案的讀寫,使用者可以參考MATLAB幫助文檔。
MATLAB中實作文本檔案讀寫的函數如表13-1所示。
表13-1 MATLAB中文本檔案讀寫函數
函 數
功 能
csvread
讀入以逗号分隔的資料
csvwrite
将資料寫入檔案,資料間以逗号分隔
dlmread
将以 ASCII 碼分隔的數值資料讀入到矩陣中
dlmwrite
将矩陣資料寫入到檔案中,以 ASCII 分隔
textread
從文本檔案中讀入資料,将結果分别儲存
textscan
從文本檔案中讀入資料,将結果儲存為單元數組
下面詳細介紹這些函數。
1. csvread、csvwrite
csvread函數的調用格式如下:
● M = csvread(\'filename\'),将檔案filename中的資料讀入,并且儲存為M,filename中隻能包含數字,并且數字之間以逗号分 隔。M是一個數組,行數與filename的行數相同,列數為filename列的最大值,對于元素不足的行,以0補充。
● M = csvread(\'filename\', row, col),讀取檔案filename中的資料,起始行為row,起始列為col,需要注意的是,此時的行列從0開始。
● M = csvread(\'filename\', row, col, range),讀取檔案filename 中的資料,起始行為 row,起始列為col,讀取的資料由數組 range 指定,range 的格式為:[R1 C1 R2 C2],其中R1、C1為讀取區域左上角的行和列,R2、C2為讀取區域右下角的行和列。
csvwrite 函數的調用格式如下:
● csvwrite(\'filename\',M),将數組M中的資料儲存為檔案filename,資料間以逗号分隔。
● csvwrite(\'filename\',M,row,col),将數組M中的指定資料儲存在檔案中,資料由參數 row和col指定,儲存row和col右下角的資料。
● csvwrite寫入資料時每一行以換行符結束。另外,該函數不傳回任何值。
這兩個函數的應用見下面的例子。
例13-4 函數csvread和csvwrite 的應用。
本例首先将MATLAB的圖示轉化為灰階圖,将資料存儲在文本檔案中,再将其部分讀出,顯示為圖形。
編寫M檔案,命名為immatlab.m,内容為:
% the example of functions csvread and csvwrite
I_MATLAB= imread(\'D:\matlab.bmp\'); % read in the image
I_MATLAB= rgb2gray(I_matlab); % convert the image to gray image
figure,imshow(I_matlab,\'InitialMagnification\',100); % show the image
csvwrite(\'D:\matlab.txt\',I_matlab); % write the data into a text file
sub_MATLAB= csvread(\'D:\matlab.txt\',100,100);% read in part of the data
sub_MATLAB= uint8(sub_matlab); % convert the data to uint8
figure,imshow(sub_matlab,\'InitialMagnification\',100); % show the new image
在指令視窗中運作該腳本,輸出圖形如圖13-2所示。
(a) (b)
圖13-2 例13-3 的運作結果
該例中涉及到了少量的圖像處理内容,超出本書的範圍,感興趣的讀者可以查閱 MATLAB幫助文檔中關于Image Processing Toolbox的介紹。
2. dlmread、dlmwrite(個人覺得這個比較好用)
dlmread函數用于從文檔中讀入資料,其功能強于csvread。dlmread的調用格式如下:
● M = dlmread(\'filename\')
● M = dlmread(\'filename\', delimiter)
● M = dlmread(\'filename\', delimiter, R, C)
● M = dlmread(\'filename\', delimiter, range)
其中參數delimiter用于指定檔案中的分隔符,其他參數的意義與csvread函數中參數的意義相同,這裡不再贅述。dlmread函數與csvread函數的差别在于,dlmread函數在讀入資料時可以指定分隔符,不指定時預設分隔符為逗号。
dlmwrite函數用于向文檔中寫入資料,其功能強于csvwrite函數。dlmwrite函數的調用格式為:
● dlmwrite(\'filename\', M),将矩陣M的資料寫入檔案filename中,以逗号分隔。
● dlmwrite(\'filename\', M, \'D\'),将矩陣M的資料寫入檔案filename中,采用指定的分隔符分隔資料,如果需要tab鍵,可以用“\t”指定。
● dlmwrite(\'filename\', M, \'D\', R, C),指定寫入資料的起始位置。
● dlmwrite(\'filename\', M, attribute1, value1, attribute2, value2, ...),指定任意數目的參數,可以指定的參數見下表。
● dlmwrite(\'filename\', M, \'-append\'),如果filename指定的檔案存在,在檔案後面寫入資料,不指定時則覆寫原檔案。
● dlmwrite(\'filename\', M, \'-append\', attribute-value list),叙寫檔案,并指定參數。
● dlmwrite 函數的可用參數如表13-2所示。
表13-2 dlmwrite函數的可用參數
參 數 名
功 能
delimiter
用于指定分隔符
newline
用于指定換行符,可以選擇“pc”或者“unix”
roffset
行偏差,指定檔案第一行的位置,roffset 的基數為 0
coffset
列偏差,指定檔案第一列的位置,coffset 的基數為 0
precision
指定精确度,可以指定精确維數,或者采用 c 語言的格式,如“.5f”
3. textread,textscan
當檔案的格式已知時,可以利用textread函數和textscan函數讀入。這裡隻介紹這兩個函數應用的執行個體。
例13-5 通過%讀入檔案,按照原有格式讀取。
檔案的内容為:
Sally Level1 12.34 45 Yes
在指令視窗中輸入:
>> [names, types, x, y, answer] = textread(\'D:\mat.txt\',\'%s %s %f %d %s\', 1)
得到結果為:
names =
\'Sally\'
types =
\'Level1\'
x =
12.3400
y =
45
answer =
\'Yes\'
例13-6 函數csvread和csvwrite的應用
Sally Level1 12.34 45 1.23e10 inf NaN Yes
Joe Level2 23.54 60 9e19 -inf 0.001 No
Bill Level3 34.90 12 2e5 10 100 No
>> fid = fopen(\'D:\mat.txt\');
>> C = textscan(fid, \'%s %s �2 � %u %f %f %s\');
>> fclose(fid);
13.3 低級檔案I/O
本節介紹一些基本的檔案操作,這些操作如表13-3所示。
表13-3 MATLAB的基本檔案操作
函 數
功 能
fclose
關閉打開的檔案
feof
判斷是否為檔案結尾
ferror
檔案輸入輸出中的錯誤查找
fgetl
讀入一行,忽略換行符
fgets
讀入一行,直到換行符
fopen
打開檔案,或者擷取打開檔案的資訊
fprintf
格式化輸入資料到檔案
fread
從檔案中讀取二進制資料
frewind
将檔案的位置指針移至檔案開頭位置
fscanf
格式化讀入
fseek
設定檔案位置指針
ftell
檔案位置指針
fwrite
向檔案中寫入資料
下面重點介紹函數fprintf。該函數的調用格式如下:
count = fprintf(fid, format, A, ...),該語句将矩陣A及後面其他參數中數字的實部以 format 指定的格式寫入到fid指定的檔案中,傳回寫入資料的位元組數。
上面語句中,參數format由%開頭,共可由4個部分組成,分别如下:
● 标記(flag),為可選部分。
● 寬度和精度訓示,為可選部分。
● 類型标志符,為可選部分。
● 轉換字元,為必需部分。
1. 标記
标記用于控制輸出的對齊方式,可以選擇的内容如表13-4所示。
表13-4 标記的可選内容
函 數
功 能
示 例
負号(-)
在參數左側進行判别
%-5.2d
加号(+)
在數字前添加符号
%+5.2d
空格
在數字前插入空格
% 5.2d
0
在數字前插入0
.2d
2. 寬度和精度訓示
使用者可以通過數字指定輸出數字的寬度及精度,格式如下:
● o,指定數字的寬度;
● %6.2f,指定數字的寬度及精度;
● %.2f,指定數字的精度。
例13-6 fprintf函數寬度和精度訓示符示例。
在指令視窗中輸入如下指令:
>> file_type = fopen(\'D:\type.txt\',\'w\');
>> fprintf(file_h, \'%6.2f .8f\n\', 1.2, -43.3);
>> fprintf(file_h, \'o f\n\', 1.2, -43.3);
>> fprintf(file_h, \'%.2f %.8f\n\', 1.2, -43.3);
>> fclose(file_h)
ans =
0
打開該檔案,其内容為:
1.20 -43.30000000
1.200000 -43.300000
1.20 -43.30000000
從上述結果可以看出寬度和精度控制的效果。
3. 轉換字元
轉換字元用于指定輸出的符号,可以選擇的内容如表13-5所示。
表13-5 格式化輸出的标志符及意義
标 志 符
意 義
%c
輸出單個字元
%d
輸出有符号十進制數
%e
采用指數格式輸出,采用小寫字母 e,如:3.1415e+00
(續表)
标 志 符
意 義
%E
采用指數格式輸出,采用大寫字母 E,如:3.1415E+00
%f
以定點數的格式輸出
%g
%e及%f的更緊湊的格式,不顯示數字中無效的 0
%G
與%g相同,但是使用大寫字母E
%i
有符号十進制數
%o
無符号八進制數
%s
輸出字元串
%u
無符号十進制數
%x
十六進制數(使用小寫字母a-f)
%X
十六進制數(使用大寫字母A-F)
其中 %o、%u、%x、%X支援使用子類型,具體情況這裡不再贅述。格式化輸出标志符的效果見下面的例子。
例13-7 fprintf 格式化輸出示例。
>> x = 0:.1:1;
>> y = [x; exp(x)];
>> fid = fopen(\'exp.txt\', \'wt\');
>> fprintf(fid, \'%6.2f .8f\n\', y);
>> fclose(fid)
ans =
0
顯示該檔案:
>> type exp.txt
0.00 1.00000000
0.10 1.10517092
…
0.90 2.45960311
1.00 2.71828183
例13-9 利用 fprintf 函數在顯示器上輸出字元串
>> fprintf(1,\'It\'\'s Friday.\n\')
It\'s Friday.
在該例中,利用1表示顯示器,并且用兩個單引号顯示單引号,使用\n進行換行。在格式化輸出中,這類符号稱為轉義符。MATLAB中的常用轉義符如表13-6所示。
表13-6 MATLAB中的常用轉義符
轉 義 符
功 能
\b 倒退
\f 表格填充
\n 換行符
\r 回車
\t tab
\\ 反斜線
\\'\' 或 \'\' 單引号
%% 百分号
13.4 利用界面工具導入資料
除前面幾節介紹的函數外,也可以通過界面工具将資料導入到工作區中。本節介紹利用工作區浏覽器中的工具導入資料。
選擇工作區浏覽器工具欄中的“Import Data”,選擇待導入的檔案,這裡我們選擇了一個文本檔案,其内容為逗号分隔的數字,打開視窗如圖13-3所示。