網頁標題: 13 檔案讀寫

Warning: fopen(/home/crazy/www/cmsb/bcj/has_read.php): failed to open stream: Permission denied in /home/crazy/www/compose/reading.php on line 2070

Warning: fputs() expects parameter 1 to be resource, bool given in /home/crazy/www/compose/reading.php on line 2072

Warning: fclose() expects parameter 1 to be resource, bool given in /home/crazy/www/compose/reading.php on line 2073
 



 本文介紹 AutoIt 腳本如何讀寫硬碟裡的檔案,以及某些與檔案相關的操作。讀寫檔案有「讀」、「寫」二種情形,「讀」情形下程式可從任何位置起讀取檔案,「寫」情形表示程式有權限修改檔案內容,也可以「讀」整個檔案。根據是否保留檔案原始內容又將「寫」分成「追加」與「覆寫」,「追加」即保留原始內容供讀但禁止修改,「覆寫」會將檔案原始內容全數去除。另外「寫」操作允許程式創立原本不存在的檔案,對這種檔案而言「追加」、「覆寫」就無區別了。

 下面的範例展示如何讀取一個文件並用 MsgBox 顯示它的每行。假設該文件檔名為 test.txt, 放在與程式碼檔案相同目錄下。

 上例對 test.txt 依序進行開、讀、關等三個動作,並比之前的範例多引入 FileConstants.au3 以使用跟檔案操作的內建函式相關的常數,如此例的 $EOF.

 FileOpen 用來開檔,共有二個參數,第一個參數指定檔名或路徑,第二個參數指定操作模式。上例省略第二參數時,預設模式為「讀」,不想省略可以寫 FileOpen("test.txt", $FO_READ). 模式另外有 $FO_APPEND 為追加,$FO_OVERWRITE 為覆寫,以上三個 $FO_ 開頭的選項是一個單選題。若成功開檔,將得到一個控制碼 (handle), 到關檔前都可將它做為參數給讀、寫等操作的函式。當開檔不幸失敗,FileOpen 就會傳回 -1, 這是一個以回傳值反映函式執行狀況的例子。

 FileReadLine 從文件裡讀取一行,第一個參數就是剛才得到的控制碼,第二個參數在此也被省略,可用來指定行號,未指定則往下一行讀取。當讀到文件尾端,將把 @error 設為 $EOF, 意即 End Of File, 以此為讀檔結束的判斷依據。但是讀到文件尾不代表檔案會自己關閉或再也無法讀取,我們仍可使用其他內建函式改變讀檔的位置,或者從參數指定行號來讀。

 FileClose 就是將檔案關閉,從此以後控制碼即無效,不過可用 $fh 去接收別次開檔的控制碼。關檔代表釋放對該檔案的佔有狀態,讓別的程序可以讀寫它,雖然忘了關檔時一旦執行結束會自動釋放對所有檔案的佔有狀態,但是程式碼內關檔是良好習慣,不會一直霸佔檔案資源而不利用造成浪費。

 另外 FileReadLine 第一個參數也可以直接填入檔名或路徑,該檔被讀完指定行後立即關閉。雖然會自己關檔很方便簡潔,但若檔案要頻繁讀取,應當使用 FileOpen 以控制碼方式操作,以免每次讀取時都要開檔關檔造成效率不彰。

 跟檔案相關的操作,除了關檔之外,養成檢查錯誤也是好習慣,尤其開檔,以避免不預期的意外造成執行結果異常。

 註:開檔的錯誤檢查 @error = -1 寫成 @error = $EOF 也可以,不過本文一律寫成 -1.


 假設與範例 13-1 相同環境,下面示範「寫」模式的檔案操作:

 此例用到 FileWriteLine 可在檔案尾端追加文字內容,參數只有檔案控制碼或檔名,以及要寫入的文字內容。需注意的是,若檔案最後一行不是空行,則這段內容會被黏在該行之後,並讓最後為空行。

 重新開檔後改用 FileRead 讀取內容,它有第二個可選參數用來指定讀取的字元數目,指定負值或像上例未指定則讀入整個檔案。FileRead 完後 @extended 會被設為成功讀取的字元數目,有興趣的讀者可以將上例的 @extended 印出來看看。


 以上皆針對「文件」的操作,但許多檔案內容並非文字,如 PDF, 影音跟 Microsoft Office 產生的檔案,想解讀它們就必須不使用文字方式來看待而要用二進位 (Binary). FileOpen 的「模式」參數可以指定 $FO_BINARY, 是一個複選題,與讀、寫的設定互相獨立。假設 test.pdf 置於腳本相同目錄下。

 $FO_BINARY 就是要求以二進位模式處理開啟的檔案。這個模式會把檔案內容原封不動地送進 $data, 跟文件模式最大差異在於是否處理換行。

 這邊 @extended 顯示的是「位元組」數目,因為二進位模式讀檔的基本單元是位元組而不是「字元」。另外此處將 MsgBox 提到 FileClose 之前,以免 FileClose 執行而改變 @extended 值,印出錯誤答案。


 以下簡介 FileOpenDialog 內建函式,一個展現圖形使用者介面幫助選擇檔案的函式。以下將範例 13-1 改成讓使用者自己選擇輸入的文件檔:

 FileOpenDialog 第一個參數為視窗標題,第二個參數指定對話開啟時預設的資料夾路徑,第三個參數指定顯示出的檔案類型,第四個參數是決定該函式行為的旗標。

 這裡第二個參數 "." 指的是目前的工作目錄,因為腳本執行後並未改變工作目錄,所以它跟 @ScriptDir 代表的目錄一樣。注意 FileOpenDialog 執行完後可能會改變腳本的工作目錄。

 檔案類型的字串有其格式,在對話裡它是一個下拉式方塊,上例只在該方塊內產生一個項目。若要加入「所有檔案」項目可以寫成 "文字文件 (*.txt)|所有檔案 (*.*)", 以 | 即可區隔兩個項目,每個項目裡都有一對小括號,內含被允許顯示的檔案檔名的格式。

 檔名格式裡的 * 是萬用 (wildcard) 字元,對岸稱「通配符」,表示 0 個至無限個字元,寫 *.txt 意思是限制其副檔名為 txt. 若一個項目含有多種副檔名被允許顯示,可以寫成 "HTML 網頁 (*.htm;*.html)", 不同檔名格式間以分號區隔,同時挑出副檔名為 htm 及 html 的檔案。

 在此第四個是可選參數,$FD_FILEMUSTEXIST 指定檔案必須存在,否則按下「開啟」會出現「沒有找到檔案。請確認是否已提供正確的檔案名稱。」這樣的提示。此處有四個複選題選項 $FD_FILEMUSTEXIST, $FD_PATHMUSTEXIST, $FD_MULTISELECT, 和 $FD_PROMPTCREATENEW, 不過其他三個選項的使用不在本文範圍。

 FileOpenDialog 有第五個也是可選的參數,允許程式指定預設檔名,若有指定則在對話開啟時會以反白型態填在「檔名」欄內。

 對話結束後若 @error 不是 0, 則表示有錯誤發生。是 1 表示選擇檔名失敗,可能使用者按了「取消」,是 2 表示指定給「檔案類型」下拉式方塊的字串沒有遵守格式,不過當該處是程式碼裡設好且確認格式正確時,像上例就只檢查 @error 不是 0 而進入 If 分支內。

 如果成功選擇檔案,FileOpenDialog 會回傳被選擇的完整路徑,之後可像上例般用 FileOpen 去開檔、讀檔。

 另一個也很常見的對話是「另存新檔」,在 FileSaveDialog 內建函式裡,留給有興趣的讀者自行摸索。它的參數與 FileOpenDialog 完全一樣,不過第四個參數只有 $FD_PATHMUSTEXIST 跟 $FD_PROMPTOVERWRITE 有效,後者可在指定的檔名已存在時跳視窗提醒使用者確認檔案可能被覆寫。它的回傳值跟 @error 的設置也同 FileOpenDialog.

 注意:以上二個對話 FileOpenDialog, FileSaveDialog 只負責提示使用者,程式即將進行讀檔或寫檔,可是沒要求程式在對話之後一定要進行該動作。當然,也可以在結束 FileOpenDialog 之後覆寫掉該檔案,不過身為程式設計師千萬不可以如此,請確保自己程式的行為符合使用者預期!


 最後以表格列出一些較易理解的,跟檔案、資料夾有關的內建函式,讓有興趣的讀者更深入探討它們的使用。

 註:另有一種特殊的「組態設定值」文件,副檔名 ini, AutoIt 特別設置 IniDelete, IniRead, IniReadSection, IniReadSectionNames, IniRenameSection, IniWrite, IniWriteSection 等七個內建函式來處理,有興趣的讀者也可自行深入探討。

函式名稱效果備註
DirCopy複製整個來源資料夾到目的地複製包含子資料夾及所有檔案
DirCreate創建新的資料夾 
DirGetSize總計資料夾內檔案大小 
DirMove移動整個來源資料夾到目的地移動包含子資料夾及所有檔案
DirRemove刪除資料夾 
FileChangeDir改變腳本的工作目錄注意用途不是替檔案改變資料夾
FileCopy複製檔案 
FileDelete刪除檔案 
FileExists檢查檔案或資料夾是否存在 
FileFlush把緩衝區內容寫入硬碟為減少因硬碟存取而降低效能,寫檔時內容會先留在緩衝區,緩衝區已滿或關檔才寫入硬碟,
該函式即程式主動要求立刻寫入硬碟
FileGetAttrib取得檔案或資料夾的屬性屬性包含「唯讀」、「隱藏」等等
FileGetEncoding檢測檔案編碼只能檢查出記事本另存新檔時列的四種編碼
FileGetPos傳回目前讀寫檔的位置以後可用 FileSetPos 把讀寫進度拉回該處
FileGetSize取得檔案大小 
FileGetTime取得檔案或資料夾的時間訊息包括修改時間、建立時間、上次存取時間
FileMove移動檔案 
FileSelectFolder開啟「瀏覽資料夾」對話 
FileSetAttrib設定檔案屬性屬性與 FileGetAttrib 所指相同
FileSetPos設定檔案讀寫位置建議先以 FileGetPos 記錄檔案某處位置
FileSetTime設定檔案或資料夾的時間訊息項目與 FileGetTime 所指相同


回 · 我的 AutoIt 學習筆記 這一篇文章封面


本文張貼者:Bo-Cheng Jhan〔張貼時間:民國105年6月5日(星期天)22點29分〕

部落格首頁


學習的故鄉首頁
本站公告:〔您越需要我們,我們就越有創意〕 本站說明書:〔發現故鄉還有改進的地方,請來信告訴原丁們〕
觀察應用學習點數 :〔咱的故鄉有您的參與,會使我們有更大的發揮空間,展現更豐富精彩的學習畫面〕 〔期待藉由無障礙網頁設計,能讓視障小朋友更愛看書、更愛寫作且更愛學習〕:盲用電腦「心得分享」
〔為了讓我們有乾淨的學習環境,請勿任意在本站散播商業廣告與不合法文件或聯結〕:本站宣示