
MATLAB程式设计入门篇档案读写.ppt
69页按一下以編輯母片標題樣式,,按一下以編輯母片,,第二層,,第三層,,第四層,,第五層,,,,*,MATLAB,程式設計入門篇:讀寫檔案,,,,,,,,按一下以編輯母片標題樣式,,按一下以編輯母片,,第二層,,第三層,,第四層,,第五層,,,,*,MATLAB,程式設計入門篇,,檔案讀寫,張智星,(Roger Jang),,,,清大資工系 多媒體檢索實驗室,1,,本章重點,很多計算工作的第一步就要是讀取資料,,MATLAB,內建許多有關檔案讀寫的函數,可對二進制檔案或,ASCII,檔案進行下列處理:,,開啟,,關閉,,儲存,2,,高階的檔案讀寫指令(,1/2,),先列出常用讀寫檔案指令,稍後將介紹用法,類別,支援檔案格式,指令,,一般資料,MAT - MATLAB workspace,load, save,,CSV - Comma separated numbers,csvread, csvwrite,,DAT - Formatted text,Importdata,,DLM - Delimited text,dlmread, dlmwrite,,TAB - Tab separated text,,試算表,XLS - Excel worksheet,Xlsread,,WK1 - Lotus 123 worksheet,wk1read, wk1write,3,,高階的檔案讀寫指令(,2/2,),類別,支援檔案格式,指令,,科學資料,CDF - Common Data FormatFITS - Flexible,cdfread, cdfwrite,,Image Transport System,Fitsread,,HDF - Hierarchical Data Format,hdfread, hdfwrite,電影,AVI - Movie,aviread,影像,TIFF, PNG, HDF, BMP, JPEG, GIF, PCX, XWD, CUR, ICO, RAS, PBM, PGM, PPM,imread, imwrite,音訊,AU, SND - NeXT/Sun sound,auread, auwrite,,WAV - Microsoft Wave sound,wavread, wavwrite,4,,csvread,使用,csvread,指令來讀取,,條件:,,資料檔案是由,逗號,分開,,只有包含數值資料,,Ex:csvread01.m,,fprintf('data.csv,的內容:\,n');,,type data.csv,%,列出,data.csv,的內容,,A = csvread('data.csv'),%,將,data.csv,的內容讀到矩陣,A,5,,執行結果,data.csv,的內容:,,1, 2, 3,,4, 5,,6, 7, 8, 9,,A =,,1 2 3 0,,4 5 0 0,,6 7 8 9,,,csvread,會傳回一個數值矩陣,,其中缺席的資料將以,0,填入。
6,,dlmread,如果數值資料的分界符號(,Delimiters),不是逗點,就不能使用,csvread,指令,而要改用,dlmread,指令,,Ex:dlmread01.m,fprintf('data.dlm,的內容:\,n');,,type data.dlm,,%,列出,data.dlm,的內容,,A = dlmread(‘data.dlm’, ‘\t’),,%,將,data.dlm,的內容讀到矩陣,A,,資料是以定位鍵隔開,,7,,執行結果,data.dlm,的內容:,,1,,2 3,,4 5,,6 7,,8 9,,A =,,1 2 3 0,,4 5 0 0,,6 7 8 9,,上例中,data.dlm,的資料是以定位鍵(,Tab,),隔開,因此,dlmread,指令的第二個引數是,‘,\,t,’,,,以代表定位鍵,8,,textread,如果檔案資料包含,數值,及,字串,,我們就必須改用,textread,指令,,Ex:textread01.m,fprintf('data.txt,的內容:\,n');,,type data.txt,%,列出,data.txt,的內容,,[,name, hobby, age] = textread('data.txt', '%s%s%d'),9,,執行結果,data.txt,的內容:,,Timmy OnlineGames 13,,Annie Chatrooms 10,,Roger Tennis 41,,name =,,'Timmy,‘,,'Annie',,'Roger',,hobby =,,'OnlineGames',,'Chatrooms',,'Tennis',,age =,,13,,10,,41,在上述範例中,,data.txt,包含三個欄位(或是三直行的資料),,textread,可在第二個引數指定資料型態,,例如上例中 %,s,代表字串,%,d,代表整數,,也同時將讀入的資料設定到不同的輸出引數,,由於資料型態的不同,輸出引數也有不同的型態,,以上述範例來說,,name,和,hobby,都是字串異值陣列,而,age,則是數值陣列。
10,,使用定位鍵來分隔欄位,上例中,我們利用空格來分隔欄位,,如果欄位值本身也有空格 ?,,一般常見的作法,是使用定位鍵來分隔欄位,,Ex:textread02.m,fprintf('data2.txt,的內容:\,n');,,type data2.txt,%,列出,data2.txt,的內容,,[,name, hobby, age] = textread('data2.txt', '%s%s%d', 'delimiter', '\t'),11,,執行結果,結果與前一例相同,,textread,指令中加上對分界字元(,Delimiters),的定義,就可以讀出由定位鍵所分隔的資料檔案,,若不指定時,預設為空白鍵,,12,,讀取文字檔,textread,也可以讀取一個文字檔,同時把檔案內的每一列文字變成字串異質陣列裡面的每一個元素,,Ex:textread03.m,Contents = textread('textread03.m','%s','delimiter','\n','whitespace','');,,class(contents),%,印出,contents,的資料類別,,contents{1},%,列出,contents,第一列,,contents{2},%,列出,contents,第二列,13,,執行結果,ans =,,cell,,ans =,,contents=textread('textread03.m','%s','delimiter','\n','whitespace','');,,ans =,,class(contents) %,印出,contents,的資料類別,,,上例使用,textread,讀入,textread03.m(,也就是此範例檔案),並顯示此檔案的第一列和第二列。
textread,指令的用法還有很多,功能也很強大,,在,MATLAB,下輸入「,help textread」,,可以得到完整的技術支援14,,若只是要簡單地將一個檔案的內容送到一個字串,可以使用,,指令,,Ex:,範例16-6:,out = (,‘,data2.txt,’,);,,class(out),,size(out),15,,執行結果,ans =,,char,,ans =,,1 64,,,上例中,,,指令會將檔案,data2.txt,的內容送到字串變數,out,,class(out),的值是,char,,顯示,out,的資料型態是字串,,size(out),顯示字串,out,的長度是 6416,,影像與音訊檔案,有關於影像檔案的讀寫,請參閱本書第十九章「影像顯示與讀寫」;,,有關音訊檔案的讀寫,請參閱本書第二十章「音訊讀寫、錄製與播放」17,,更繁複的文字檔案格式,一般情況下,,盡量採取先前介紹的內建指令來進行讀寫,效率才會高資料格式比較繁複時,,需要一列一列讀進來,再進行剖析(,Parsing),,相關指令將在以下介紹18,,開啟檔案,無論讀寫,ASCII,或二進制檔案,都必需先用,fopen,函數來開啟檔案,語法如:,,fid = fopen(, permission),,其中,,表示欲讀寫的檔案名稱,,permission,則表示欲對檔案進行的處理方式,可以是下列任一字串:,,l,‘,r,’,:,只准讀取(,reading),檔案,,l,‘,w,’,:,只准寫入(,writing),檔案,,l,‘,a,’,:,只准加入(,appending),檔案,,l 'a+':,可讀取及加入檔案(,reading and appending),,省略第二個引數,,permission,的預設值就是,‘,r,’,。
19,,有關,fopen,在,windows,下,,permission,字串必需能夠分辨,binary,或,ASCII,檔案例如:若要讀,binary,檔案,則,permission,字串必需是,“,rb,”,,,fopen,另外支援很多,permission,字串,可輸入 「,help fopen」,得到完整的資訊fopen,函數傳回一個檔案辨識碼(通常是個大於,2,的整數),我們可用此辨識碼來對此檔案進行各種讀寫的處理20,,Ex:fopen01.m,上例可知當檔案不存在時,回傳的,fid,是,–,1,,同時,message,會包含相關的錯誤資訊[,fid, message] = fopen('no_such_file', 'r');,,fprintf('fid = %d\n', fid);,,fprintf('message = %s\n', message);,fid = -1,,message = Sorry. No help in figuring out the problem . . .,21,,Ex:fopen02.m,若開啟成功,則傳回的,fid,是一個大於 2 的整數,而且傳回的,message,是一個空字串,例如:,[fid, message] = fopen('fopen02.m', 'r');,,fprintf('fid = %d\n', fid);,,fprintf('message = %s\n', message);,fid = 3,,message =,22,,提示,為了安全起見,最好在每次使用,fopen,時,都測試其傳回的,fid,是否為有效值。
輸出位置,,MATLAB,使用,fid=1,來代表「標準輸出(,Standard Output),,fid=2,代表「標準錯誤輸出」(,Standard Error),,若使用,fid=1,或,2,時,可不使用,fopen,來開啟檔案,,Try this to see their difference:,,fprintf(1, 'This is standard output!\n');,,fprintf(2, 'This is standard error!\n');,23,,關閉檔案,完成檔案的讀寫之後,記得要使用,fclose,函數來關閉檔案,用法如下:,,status = fclose(fid);,,若一切順利,,fclose,傳回 0若無法順利關閉檔案,則,fclose,傳回 -1為避免因開啟檔案過多而造成系統資源浪費,一般在完成檔案的讀寫後,即應使用,fclose,來關閉檔案,24,,提示,若要一次關閉所有開啟的檔案,可用,fclose('all'),或是,fclose all開啟及關閉檔案都是比較耗時的函數,因此盡量不要將他們置於迴圈之中,以提高程式執行效率25,,讀取,ASCII,檔案(,1/2,),fgetl,函數:,,可將,ASCII,檔案的內容中的某一列讀出,,並將該列的,ASCII,內容以轉成字串傳回。
Ex:,fgetl01.m,fid = fopen('mean.m', 'r');,,while feof(fid)==0,% feof,測試檔案指標是否已到達結束位置,,,line = fgetl(fid);,,disp(line);,,end,26,,讀取,ASCII,檔案(,2/2,),執行上述程式後,,MATLAB,會,…,,先在目前目錄找尋,mean.m,,若找不到,再根據搜尋路徑,找出,mean.m,指令的位置然後再將其內容一列一列地列出輸入「,which mean」,可顯示檔案所在的路徑,,fgets,和,fgetl,均可由檔案讀取一列資料:,,fgetl,會取得一列,但不包含換列字元,,fgets,則保留換列字元,27,,應用:模擬,unix,的,grep,指令,grep,:用來找出包含某一特定字串的一列,function grep(, pattern),,fid = fopen(, 'r');,,line_number = 0;,,while feof(fid) == 0,,,line = fgetl(fid);,,matched = findstr(line, pattern);,,if ~isempty (matched),,fprintf('%d: %s \n', line_number,line);,,end,,line_number = line_number + 1;,,end,,fclose(fid);,,28,,執行結果,如欲列出,grep.m,中包含 ',matched',字串的每一列,可輸入如下:,,,>>,grep('grep.m', 'matched'),,6: matched = findstr(line, pattern);,,7: if ~isempty (matched),,,若要進行更複雜的字串比對,請參考本書姊妹作「,MATLAB,程式設計:進階篇」中的第四章「通用運算式」。
例如要在一個檔案中找出「,b,和,d,中間夾1至3個母音」的英文字,,29,,fscanf,函數,fscanf,可對,ascii,檔案作更精確的讀取,用法如下:,,matrix = fscanf(fid, format),,其中,fid,是欲讀取之檔案的辨識碼,,format,是格式指定字串(,Format Specifier),,常用的格式指定字串有下列幾種:,,%s:,字串,,%d:10,進位的整數,,%g:,雙倍精準(,Double-precision),的浮點數,,其他各種格式指定字串可輸入,help fscanf,來得到詳細的說明,30,,Ex:fscanf01.m,有一文字檔,test.txt,如下:,1 4 9 16 25,,36 49 64 81 100,欲使用,fscanf,指令讀取其內容,可輸入如下:,fid = fopen('test.txt', 'r');,,myData = fscanf(fid, '%g');,,fclose(fid);,,myData,%,顯示,myData,31,,執行結果,myData =,,1,,4,,9,,16,,25,,36,,49,,64,,81,,100,上例顯示了,MATLAB,的,fscanf,指令和,C,的,fscanf,指令的最大不同:,,MATLAB,的,fscanf,指令是向量化的(,Vectorized),,只要讀入資料的型態正確,,MATLAB,的,fscanf,指令會一再執行,,同時把所得結果存放於一個向量並回傳。
32,,sscanf,sscanf,函數和,fscanf,的功能很類似,,sscanf,函數從字串(,Strings),中讀取資料,,ex:sscanf01.m,str = num2str([pi, sqrt(2), log10(3)]),%,建立一字串,str,,retrieved = sscanf(str,,',%g,',),%,擷取,str,中的,double,str =,,3.1416 1.4142 0.47712,,retrieved =,,3.1416,,1.4142,,0.4771,33,,寫入,ASCII,檔案,fprintf,函數可將資料依格式指定字串來寫入,ASCII,檔案,其使用語法如下:,,fprintf(fid, format, y),,其中,fid,是欲寫入之檔案的辨識碼,,format,是格式指定字串,用以指定資料寫至檔案的格式,,y,是,MATLAB,的資料變數,,常用的格式指定字串有下列幾種:,,%e:,科學記號,即將數值表示成,a×10b,的形式,,%f:,固定欄寬(含整數與小數部份)的表示法,,%g:,自動選取 %,e,或 %,f,,其他各種格式指定字串可輸入,help fprintf,來得到詳細的線上說明。
34,,應用:將平方根表寫入檔案,Ex:fprintf01.m,x = 1:10;,,y = [x; sqrt(x)];,,fid = fopen('squareRootTable.txt', 'w');,,fprintf(fid, 'Table of square root:\r\n');,,fprintf(fid, '%2.0f => %10.6f\r\n', y);,,fclose(fid);,,dos('start squareRootTable.txt');,%,開啟,squareRootTable.txt,35,,執行結果,在上例中,…,,%2.0,f,印出的總欄寬為 2,且不帶小數,,%10.6,f,印出的總欄寬為 10,包含 6位的小數,,請自行試驗後開啟,squareRootTable.txt,來驗證,squareRootTable.txt,36,,sprintf,sprintf,函數和,fprintf,函數的功能很類似,,sprintf,將資料以字串形式傳回,,Ex:,>>,str = sprintf('log(%f) = %e\n', 2, log(2)),str =,,log(2.000000) = 6.931472e-001,37,,暫存目錄,某些應用需要用到暫存目錄及暫存檔案。
例如:產生一個,html,檔案,再使用瀏覽器開啟欲取用系統的暫存目錄,可用,tempdir,如下:,,,>>,directory = tempdir,,Result:,,directory =,,C:\Users\jang\AppData\Local\Temp\,,38,,暫存檔案,欲開啟一暫存檔案,可用,tempname,,如下:,,>>,= tempname,,Result:,,,= C:\Users\jang\AppData\Local\Temp\tpda998b2b_cb6f_4b68_9814_6dbab1d44abd,39,,提示,上述範例是在,Windows 7,進行測試,,不同系統下,tempdir,和,tempname,會依作業系統的環境變數而產生不同的回傳字串,,若是在,Windows 98,作業系統下,,tempdir,傳回的字串可能是,,’,C:\windows\temp\,’,,,tempname,傳回的字串可能是,,,’,C:\WINDOWS\TEMP\tp512124,’,40,,應用:產生暫存的,HTML,檔案,以下利用,tempname,產生一個暫存的,HTML,檔案,然後再將此檔案顯示在瀏覽器。
Ex: writeHTML.m,= [tempname, '.html'];,,fid = fopen(, 'w');,,fprintf(fid, '\n');,,fprintf(fid, 'This is a test homepage written by MATLAB!\n');,,fprintf(fid, '');,,fclose(fid);,,dos(['start ', ]);,%,啟動和 .,html,相連結的應用程式,41,,執行結果,上例產生之網頁如下:,當,MATLAB,的計算結果可用列表(,Table),或多媒體檔案(如影像、聲音、動畫等)來呈現時,由網頁來顯示這些結果是不錯的選擇42,,網路檔案的讀取,MATLAB,也可以直接讀取網路上的檔案,,通常我們是採用,URL(Universal Resource Locator),的方式來指定這些網路上的檔案:,,一般網頁:,,,FTP,,,本機硬碟檔案:,,:\winnt\matlab.ini,43,,urlread,上例中使用,urlread,指令來讀取筆者在清華大學資訊系的首頁,同時將結果指定到字串變數,contents,Ex: urlread01.m,contents = urlread(''); disp(contents);,44,,執行結果,<,HTML>,,,,点击阅读更多内容
