實驗6 檔案讀寫與多執行緒
1基礎知識
檔案與檔案路徑
檔案有兩個關鍵屬性:檔名和路徑。檔名中的最後一個句點之後的部分被稱為檔案的“副檔名”,它指明瞭檔案的型別。路徑指明瞭檔案在計算機上的位置。在Windows中,路徑書寫使用倒斜槓(\)作為資料夾之間的分隔符,而OS X和Linux中,則使用正斜槓(/)作為路徑分隔符。
檔案的型別
檔案包括兩個型別:文字檔案和二進位制檔案。一個檔案可以用“文字檔案方式”和“二進位制檔案方式”開啟,但是開啟後的操作不同(字串與位元組流)。
檔案的開啟和關閉
Python中,開啟檔案使用open()函式,其格式如下是:
<變數名> = open(<檔名>, <開啟模式>)
檔名是一個字串路徑,表明希望開啟的檔案。可以是檔案的實際名字,也可以是包含完整路徑的名字。open()函式返回一個File物件,代表計算機中的一個檔案。
開啟模式用於控制使用何種方式開啟檔案,open()函式提供7種基本的開啟模式,如下表所示:
檔案的開啟模式 |
含義 |
‘r’ |
只讀模式,如果檔案不存在,返回異常FileNotFoundError,預設值 |
‘w’ |
覆蓋寫模式,檔案不存在則建立,存在則完全覆蓋 |
‘x’ |
建立寫模式,檔案不存在則建立,存在作為返回異常FileExistsError |
‘a’ |
追加寫模式,檔案不存在則建立,存在則在檔案最後追加內容。 |
‘b’ |
二進位制檔案模式 |
‘t’ |
文字檔案模式,預設值 |
‘+’ |
與r/w/x/a一同使用,在原功能基礎上增加同時讀寫功能 |
檔案使用結束後要用close()方法關閉,釋放檔案的使用授權,該方法的使用方式如下:
<變數名>.close()
檔案的讀寫
在擁有一個File物件之後,就可以讀取它的內容。Python中提供4中常用的檔案內容讀取方法,如下表所示:
操作方法 |
含義 |
<file>.readall() |
讀入整個檔案內容,返回一個字串或位元組流 |
<file>.read(size=-1) |
從檔案中讀入整個檔案的內容,如果給出引數,讀入前size長度的字串或位元組流 |
<file>.readline(size=-1) |
從檔案中讀入一行內容,如果給出引數,讀入該行前size長度的字串或位元組流 |
<file>.readlines(hint=-1) |
從檔案中讀入所有行,以每行為元素形成一個列表,如果給出引數,讀入hint行 |
Python中也提供了3個與檔案內容寫入有關的方法。但是,如果開啟檔案時用讀模式,就不能寫入檔案,需要以“寫模式”(‘w’)或“新增模式”(‘a’)開啟該檔案。
如下表所示:
方法 |
含義 |
<file>.write(s) |
向檔案寫入一個字串或位元組流 |
<file>.writelines(lines) |
將一個元素全為字串的列表寫入檔案 |
<file>.seek(offset) |
改變當前檔案操作指標的位置,offset的值: 0:檔案開頭;1:當前位置;2:檔案結尾 |
對於作業系統來講,一個任務就是一個程序(Process)比如開啟一個瀏覽器就是啟動一個瀏覽器程序,開啟一個記事本就啟動了一個記事本程序,開啟兩個記事本就啟動了兩個記事本程序,開啟一個Word就啟動了一個Word程序。有些程序還不止同時幹一件事,比如Word,它可以同時進行打字、拼寫檢查、列印等事情。在一個程序內部,要同時幹多件事,就需要同時執行多個“子任務”,我們把程序內的這些“子任務”稱為執行緒(Thread)。由於每個程序至少要幹一件事,所以,一個程序至少有一個執行緒。
我們前面編寫的所有的Python程式,都是執行單任務的程序,也就是隻有一個執行緒。如果我們要同時執行多個任務怎麼辦?
有兩種解決方案:一種是啟動多個程序,每個程序雖然只有一個執行緒,但多個程序可以一塊執行多個任務。還有一種方法是啟動一個程序,在一個程序內啟動多個執行緒,這樣,多個執行緒也可以一塊執行多個任務。當然還有第三種方法,就是啟動多個程序,每個程序再啟動多個執行緒,這樣同時執行的任務就更多了,當然這種模型更復雜,實際很少採用。
總結一下就是,多工的實現有3種方式:
多程序模式;
多執行緒模式;
多程序+多執行緒模式。
同時執行多個任務通常各個任務之間並不是沒有關聯的,而是需要相互通訊和協調,有時,任務1必須暫停等待任務2完成後才能繼續執行,有時,任務3和任務4又不能同時執行,所以,多程序和多執行緒的程式的複雜度要遠遠高於我們前面寫的單程序單執行緒的程式。
2實驗步驟
2.1 檔案讀取
新建一個名為ex6_1.txt,在該檔案中輸入一首古詩:
白日依山盡
黃河入海流
欲窮千里目
更上一層樓
將檔案儲存到D盤。輸入如下程式碼讀取檔案內容:
1 2 3 |
textFile = open("D:\ex6_1.txt","rt") print(textFile.read()) textFile.close() |
在第二行,我們使用了read()方法來讀取檔案內容,該方法返回了儲存在該檔案中的字串。我們也可以使用上表中的其他方法,請修改上面的程式碼,探索readline()和readlines()的用法。注意,我們也可以使用readlines()方法,從該檔案取得一個字串列表,其中的每個字串就是文字中的每一行。
2.2檔案寫入
下面我們來探索檔案寫入的方法,請輸入如下程式碼:
p1 2 3 4 5 6 7 8 |
textFile = open("D:\ex6_1.txt","w") textFile.write("鋤禾日當午\n") textFile.write("汗滴禾下土\n") textFile.close() textFile = open("D:\ex6_1.txt","r") print(textFile.read()) textFile.close() |
通過觀察結果,我們發現這段程式碼的作用是完全覆蓋之前檔案的內容,重新寫入新詩句。在第2行和第3行,呼叫了write()函式,並像該函式內傳遞了兩個字串,注意這裡是包括換行符的。現在將第1行的<開啟模式>從‘w’變成‘a’,請觀察輸出結果,並解釋原因。
2.3 多程序程式設計樣例
通過多程序程式設計,進行多工處理。Python中內建了threading模組處理多執行緒。啟動一個執行緒的方法是把一個函式傳入並建立Thread例項,然後呼叫start()方法開始執行。然而,多執行緒和多程序最大的不同在於,多程序中,同一個變數,各自有一份拷貝存在於每個程序中,互不影響,而多執行緒中,所有變數都由所有執行緒共享,所以,任何一個變數都可以被任何一個執行緒修改,因此,執行緒之間共享資料最大的危險在於多個執行緒同時改一個變數。因此,我們需要確保一個執行緒修改變數值時,別的執行緒一定不能更改這個變數值,這就好比我們給變數加了一把鎖。
現在舉個例子,假設你是一個廚師,同一時刻只能處理一件事情。你需要製作“醋溜白菜”和“青椒牛肉”這兩道菜。廚師等同於CPU,這兩道菜的製作過程代表兩個執行緒,即“做醋溜白菜”和“做青椒牛肉”兩個執行緒。“做醋溜白菜”執行緒包含三個階段:洗白菜、切白菜、炒白菜。“做青椒牛肉”執行緒也包含三個階段:清洗牛肉、切青椒和牛肉、炒牛肉。假定上述兩個不同執行執行緒的每個製作階段的執行時間都為4秒。即洗白菜、炒白菜、切白菜、洗牛肉、切牛肉、炒牛肉等階段所消耗廚師的時間為4秒鐘。程式碼如下(略)
3. 實驗練習
3.1 請結合之前學到的遍歷方法(使用for迴圈),建立一個名為ex6_2.txt的新檔案,通過Python程式遍歷操作將ex6_1.txt的內容複製到新檔案ex6_2.txt中。、
3.2 遍歷誅仙txt檔案,統計‘張小凡’出現的次數。
注:只發送程式碼