1 / 66

檔案讀寫

檔案讀寫. 方煒 台大生機系. 本章重點. MATLAB 內建許多有關檔案讀寫的函數 對二進制檔案或 ASCII 檔案都可以進行處理 開啟 關閉 儲存. 高階的檔案讀寫指令. 先列出常用讀寫檔案指令,稍後將介紹用法. 高階的檔案讀寫指令( cont). csvread. 使用 csvread 指令來讀取 條件: 資料檔案是由 逗號 分開 只有包含數值資料 Ex:csvread01.m. fprintf('data.csv 的內容: n'); type data.csv % 列出 data.csv 的內容

selah
Download Presentation

檔案讀寫

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 檔案讀寫 方煒 台大生機系

  2. 本章重點 • MATLAB 內建許多有關檔案讀寫的函數 • 對二進制檔案或 ASCII 檔案都可以進行處理 • 開啟 • 關閉 • 儲存

  3. 高階的檔案讀寫指令 • 先列出常用讀寫檔案指令,稍後將介紹用法

  4. 高階的檔案讀寫指令(cont)

  5. csvread • 使用 csvread 指令來讀取 • 條件: • 資料檔案是由逗號分開 • 只有包含數值資料 • Ex:csvread01.m fprintf('data.csv 的內容:\n'); type data.csv % 列出 data.csv 的內容 A = csvread('data.csv') % 將 data.csv 的內容讀到矩陣 A

  6. result 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 填入。

  7. dlmread • 如果數值資料的分界符號(Delimiters)不是逗點,就不能使用 csvread 指令,而要改用 dlmread 指令 • Ex:dlmread01.m fprintf('data.dlm 的內容:\n'); type data.dlm % 列出 data.dlm 的內容 A = dlmread('data.dlm', '\t') % 將 data.dlm 的內容讀到矩陣 A

  8. Result 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’,以代表定位鍵

  9. textread • 如果檔案資料包含數值及字串,我們就必須改用 textread 指令 • Ex:textread01.m fprintf('data.txt 的內容:\n'); type data.txt % 列出 data.txt 的內容 [name, hobby, age] = textread('data.txt', '%s%s%d')

  10. result 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 則是數值陣列。

  11. 使用定位鍵來分隔欄位 • 上例中,我們利用空格來分隔欄位 • 如果欄位值本身也有空格 ? • 改用定位鍵來分隔欄位 • Ex:textread02.m fprintf('data2.txt 的內容:\n'); type data2.txt % 列出 data2.txt 的內容 [name, hobby, age] = textread('data2.txt', '%s%s%d', 'delimiter', '\t')

  12. result • 結果與前一例相同 • textread 指令中加上對分界字元(Delimiters)的定義,就可以讀出由定位鍵所分隔的資料檔案 • 若不指定時,預設為空白鍵

  13. 讀取文字檔 • textread 也可以讀取一個文字檔 • 同時把檔案內的每一列文字變成字串異質陣列裡面的每一個元素 • Ex:textread03.m Contents = textread('textread03.m','%s','delimiter','\n','whitespace',''); class(contents) % 印出 contents 的資料類別 contents{1} % 列出 contents 第一列 contents{2} % 列出 contents 第二列

  14. Result ans = cell ans = contents=textread('textread03.m','%s','delimiter','\n','whitespace',''); ans = class(contents) % 印出 contents 的資料類別 • 上例使用 textread 讀入 textread03.m(也就是此範例檔案),並顯示此檔案的第一列和第二列。 • textread 指令的用法還有很多,功能也很強大 • 在MATLAB下輸入「help textread」 • 可以得到完整的技術支援。

  15. Fileread • 若只是要將一個檔案的內容送到一個字串,可以使用 fileread 指令 • Ex:範例16-6:fileread01.m out = fileread(‘data2.txt’); class(out) size(out)

  16. Result ans = char ans = 1 64 • 上例中,fileread 指令會將檔案 data2.txt 的內容送到字串變數 out • class(out) 的值是 char ,顯示 out 的資料型態是字串 • size(out) 顯示字串 out 的長度是 64。

  17. 更繁複的檔案格式 • 一般情況下 • 盡量採取先前介紹的指令來進行讀寫。 • 資料格式比較繁複時 • 需要一列一列讀進來 • 再進行剖析(Parsing) • 相關指令將在以下介紹。

  18. 開啟檔案 • 無論讀寫 ASCII 或二進制檔案,都必需先用 fopen 函數來開啟檔案,語法如: • fid = fopen(filename, permission) • 其中 filename 表示欲讀寫的檔案名稱 • permission 則表示欲對檔案進行的處理方式,可以是下列任一字串: • ‘r’:只准讀取(reading)檔案 • ‘w’:只准寫入(writing)檔案 • ‘a’:只准加入(appending)檔案 • 'a+':可讀取及加入檔案(reading and appending) • 省略第二個引數,permission 的預設值就是 ‘r’。

  19. 有關fopen • 在windows下,permission 字串必需能夠分辨binary或 ASCII 檔案。 • 例如:若要讀binary檔案,則 permission 字串必需是“rb” • fopen 另外支援很多 permission 字串,可輸入 「help fopen」 得到完整的資訊。 • fopen 函數傳回一個檔案辨識碼,通常是個非負的整數,我們可用此辨識碼來對此檔案進行各種讀寫的處理。

  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. Tips: • fopen 可傳回第二個引數來顯示錯誤訊息。 • 為了安全起見,最好在每次使用 fopen 時,都測試其傳回的 fid 是否為有效值。 • MATLAB 使用 fid=1 來代表「標準輸出(Standard Output) • fid=2 代表「標準錯誤輸出」(Standard Error) • 因此在使用這兩個 fid 的值時,可以不必使用 fopen 來開啟檔案。

  23. 關閉檔案 • 完成檔案的讀寫之後,可用 fclose 函數來關閉檔案,用法如下: • status = fclose(fid); • 若一切順利,fclose 傳回 0。 • 若無法順利關閉檔案,則 fclose 傳回 -1。 • 為避免因開啟檔案過多而造成系統資源浪費,一般在完成檔案的讀寫後,即應使用 fclose 來關閉檔案

  24. Tips: • 若要一次關閉所有開啟的檔案,可用 fclose('all') 或是 fclose all。 • 開啟及關閉檔案都是比較耗時的函數,因此盡量不要將他們置於迴圈之中,以提高程式執行效率。

  25. 讀取 ASCII 檔案 • fgetl 函數: • 可將 ASCII 檔案的內容中的某一列讀出 • 並將該列的 ASCII 內容以轉成字串傳回。 • Ex:fgetl01.m fid = fopen('mean.m', 'r'); while feof(fid)==0 % feof 測試檔案指標是否已到達結束位置 line = fgetl(fid); disp(line); end

  26. 讀取 ASCII 檔案(cont) • 執行上述程式後,MATLAB 會… • 先在目前目錄找尋 mean.m • 若找不到,再根據搜尋路徑,找出 mean.m 指令的位置然後再將其內容一列一列地列出。 • 輸入「which mean」可顯示檔案所在的路徑 • fgets 和 fgetl 均可由檔案讀取一列資料: • fgetl 會捨去換行字元 • fgets 函數則保留換行字元

  27. 應用:模擬unix的grep指令 • grep :用來找出包含某一特定字串的一列 function grep(filename, pattern) fid = fopen(filename, '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. result • 如欲列出 grep.m 中包含 'matched' 字串的每一列,可輸入如下: >> grep('grep.m', 'matched') matched = findstr(line, pattern); if ~isempty (matched)

  29. fscanf • 函數fscanf可對ascii檔案作更精確的讀取,用法如下: • matrix = fscanf(fid, format) • 其中 fid 是欲讀取之檔案的辨識碼 • format 是格式指定字串(Format Specifier) • 常用的格式指定字串有下列幾種: • %s:字串 • %d:10進位的整數 • %g:雙倍精準(Double-precision)的浮點數(Floating-point Numbers) • 其他各種格式指定字串可輸入 help fscanf 來得到詳細的說明

  30. Ex: fscanf01.m • 有一文字檔 test.txt 如下: myData = 1 4 9 16 25 36 49 64 81 100 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. Ex: sscanf • sscanf 函數和 fscanf 的功能很類似 • sscanf 函數從字串(strings)中讀取資料 • ex:sscanf.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

  32. 寫入 ASCII 檔案 • fprintf 函數可將資料依格式指定字串來寫入 ASCII 檔案,其使用語法如下: • fprintf(fid, format, y) • 其中 fid 是欲寫入之檔案的辨識碼 • format 是格式指定字串,用以指定資料寫至檔案的格式 • y 是 MATLAB 的資料變數 • 常用的格式指定字串有下列幾種: • %e:科學記號,即將數值表示成 a×10b 的形式 • %f:固定欄寬(含整數與小數部份)的表示法 • %g:自動選取 %e 或 %f • 其他各種格式指定字串可輸入 help fprintf 來得到詳細的線上說明。

  33. 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

  34. Result • 在上例中… • %2.0f 印出的總欄寬為 2,且不帶小數 • %10.6f 印出的總欄寬為 10,包含 6位的小數 • typesquareRootTable.txt 來看結果

  35. sprintf • sprintf 函數和 fprintf 函數的功能很類似 • sprintf 將資料以字串形式傳回 • Ex: >> str = sprintf('log(%f) = %e\n', 2, log(2)) str = log(2.000000) = 6.931472e-001

  36. 暫存目錄 • 在某些應用上,可能需要用到暫存目錄及暫存檔案。 • 欲取用系統的暫存目錄,可用 tempdir如下: >> directory = tempdir • Result: directory = C:\DOCUME~1\jang\LOCALS~1\Temp\

  37. 暫存檔案 • 欲開啟一暫存檔案,可用 tempname,如下: >> filename = tempname • Result: filename = C:\DOCUME~1\jang\LOCALS~1\Temp\tp273132

  38. Tips • 不同系統下tempdir 和 tempname會依作業系統的環境變數而產生不同的回傳字串 • 例如在 Windows 98 作業系統下 • tempdir 傳回的字串可能是 • ’C:\windows\temp\’ • tempname 傳回的字串可能是 • ’C:\WINDOWS\TEMP\tp512124’。

  39. 應用:產生暫存的 HTML 檔案 • 以下利用 tempname 產生一個暫存的 HTML 檔案,然後再將此檔案顯示在瀏覽器。 • Ex: writeHTML.m filename = [tempname, '.html']; fid = fopen(filename, 'w'); fprintf(fid, '<html><body>\n'); fprintf(fid, 'This is a test homepage written by MATLAB!\n'); fprintf(fid, '</body></html>'); fclose(fid); dos(['start ', filename]); % 啟動和 .html 相連結的應用程式

  40. Result • 上例產生之網頁如下: • 讓MATLAB 的計算結果可用列表(Table)或多媒體檔案(如影像、聲音、動畫等)來呈現時,由網頁來顯示這些結果是不錯的選擇。

  41. 網路檔案的讀取 • MATLAB 也可以直接讀取網路上的檔案 • 通常採用 URL(Universal Resource Locator)的方式來指定這些網路上的檔案: • 一般網頁: • http://www.mathworks.com • FTP • ftp://ftp.mathworks.com/pub/pentium/Moler_1.txt • 本機硬碟檔案: • file:///C:\winnt\matlab.ini

  42. urlread • 上例中使用 urlread 指令來讀取筆者在台大生機系的首頁 • 同時disp(); 將結果指定到字串變數 contents • Ex: urlread01.m contents = urlread('http://ecaaser3.ecaa.ntu.edu.tw/cea/cea1.htm'); disp(contents);

  43. urlwrite • urlwrite可以直接在讀取網頁後,就儲存到本機硬碟中 • Ex:urlread02.m tempFile = [tempname, '.html']; % 指定暫存檔案 urlwrite('http://www.google.com.tw', tempFile); % 將網頁內容寫到檔案 dos(['start ', tempFile]); % 開啟此檔案

  44. Urlwrite(cont) • 在上例中,我們將 www.google.com.tw 的網頁內容寫到一個暫存檔案 • 然後再使用瀏覽器開啟此檔案。 • 另一個和網路相關的功能 –sendmail • 可用來寄發電子郵件 • 雖然這個功能和檔案讀寫沒有直接關係,但也在此一併說明。

  45. sendmail • Sendmail 指令的用法: • sendmail(TO, SUBJECT, MESSAGE, ATTACHMENTS) • TO:收件者 • 若是只有一位收件者,可用字串表示 • 若是有多位收件者,可以使用字串異質陣列來表示。 • SUBJECT:主題,以字串表示。 • MESSAGE:電子郵件的內容,以字串表示。 • ATTACHMENTS:附加檔案,用異質陣列來表示。

  46. Ex: sendmail01.m • 請將 to 的內容改為你自己本身的電子郵件,並試著執行一次,以確認此程式碼的正確性。 to = {'email1@aaa.bbb.ccc', 'email2@aaa.bbb.ccc'}; subject = 'Test email from a MATLAB program'; message = 'This is a test email sent via sendmail.'; attachment = {'c:\windows\matlab.ini'}; sendmail(to, subject, message, attachment);

  47. Tips • MATLAB 6.5 的sendmail 不支援中文。 • MATLAB 7.0 對 sendmail 新增了一些新功能 • 請輸入 help sendmail 來獲取最新的線上支援。 • 若要在郵件內容加入換列,可以使用 ASCII 碼「10」 • 例如:message=[’Sir:’, 10, ‘This is a test’]。

  48. 讀取二進制資料 • 用fread 函數可從檔案中讀取二進制資料 • fread會將每一個位元組看成一個整數,並將結果以一矩陣傳回。 • 例如,檔案 test2.txt 的內容如下: This is a test!

  49. Ex: fread01.m • Result: This is a test! • char 可將 myData 的整數轉成 ASCII 字元 • 取 myData 的轉制是為了使印出的效果易於閱讀 fid = fopen('test2.txt', 'r'); myData = fread(fid); char(myData') % 驗證所讀入的資料是否正確 fclose(fid);

  50. Ex: fread02.m • fread 函數可用第二個輸入引數來控制傳回矩陣的大小 fid = fopen('test2.txt', 'r'); myData = fread(fid, 4) % 只讀 4 個位元組 fclose(fid); myData = 84 104 105 115

More Related