open() 與 io 模組

40

Upload: justin-lin

Post on 26-Jan-2017

268 views

Category:

Software


2 download

TRANSCRIPT

Page 1: open() 與 io 模組
Page 2: open() 與 io 模組

8. open() 與 io 模組

• 學習目標

– 使用 open()函式

– 使用 stdin、stdout、stderr

– 認識檔案描述器

– 認識 io 模組

Page 3: open() 與 io 模組

使用 open() 函式

• 在最基本的需求上,只需要使用到它的前兩個參數:file 與 mode

Page 4: open() 與 io 模組

read()、write()、close()

Page 5: open() 與 io 模組

read() 方法

• 在未指定引數的情況下,會讀取檔案全部的內容 在指定整數引數的情況下,會讀取指定的字元數或位元組數(依開啟模式是文字或者二進位而定)

Page 6: open() 與 io 模組

• 檔案開啟模式與後續進行的操作必須符合, 否則引發 UnsupportedOperation 例外

• 可以使用 readable() 方法測試是否可讀取,使用 writable() 方法測試可否寫入

Page 7: open() 與 io 模組

readline()、readlines()、writelines()

• 對於文字模式來說,預設是讀取到'\n'、'\r'或'\r\n',都可以被判定為一行

• readline()或readlines()讀到的每一行,換行字元都一律換為'\n'。

• 對於二進位模式來說,行的判斷標準預設是遇到b'\n'這個bytes

• 文字模式在寫入的情況下, 任何'\n'都會被置換為os.linesep 的值(Windows

就是'\r\n')

Page 8: open() 與 io 模組
Page 9: open() 與 io 模組

• 逐行讀取檔案內容

Page 10: open() 與 io 模組

• Python 的檔案讀取風格:讀取一個檔案最好的方式,就是不要去 read!

Page 11: open() 與 io 模組

• 在進行檔案讀寫時,tell() 方法可以告知

目前在檔案中的位移值,單位是位元組值,檔案開頭的位移值是 0

• seek() 方法可以指定跳到哪個位移值

Page 12: open() 與 io 模組

• 可以使用 seek() 來實現隨機存取

• 可以執行 flush() 方法,將緩衝內容出清

Page 13: open() 與 io 模組

readinto()

Page 14: open() 與 io 模組

• buffering 參數用來設置緩衝策略

• 預設的緩衝策略會試著自行決定緩衝大小(通常會是 4096 或 8192 位元組)

• 或者對互動文字檔案採用行緩衝(line buffering)

• 如果 buffering 設定為0,表示關閉緩衝

• 設定為大於0 的整數值,表示指定緩衝的位元組大小

Page 15: open() 與 io 模組

• encoding 指定文字模式時的檔案編碼

• 預設採用 locale.getpreferredencoding()的傳回值作為編碼

• 如果文字檔案採用的編碼不同,讀取時就有可能會出現亂碼問題

Page 16: open() 與 io 模組

• 在正確指定 encoding 為 'UTF-8' 的情

況下,就不會有問題了:

Page 17: open() 與 io 模組

• errors 參數可指定發生編碼錯誤時,該如

何進行處理

• 在不設定的情況下,發生編碼錯誤時會引發 ValueError 的子類別例外

Page 18: open() 與 io 模組

• newlines 的指定值還可以是''、'\n'、'\r'與'\r\n'

• 如果指定了'',讀取到'\n'、'\r'或'\r\n', 都可以被判定為一行, 而readline()或readlines()讀到的每一行,一律保留來源換行字元

• 如果設定為其他'\n'、'\r'或'\r\n',那麼讀取後的換行字元就會是指定的字元

Page 19: open() 與 io 模組

• 文字模式在寫入的預設情況下,任何'\n'

都會被置換為os.linesep 的值

• 如果newline 設為''就保留原有的換行

字元,如果指定為其他值,就以指定的字元進行置換

Page 20: open() 與 io 模組

stdin、stdout、stderr

• 在 sys 模組中有個 stdin 就代表著標準輸入,而 stdout 就代表著標準輸出

• 行為上就像 open() 函式開啟的文字模式

檔案物件

Page 21: open() 與 io 模組

• 對於標準輸出或輸出, 若想二進位模式讀取或寫入, 可使用sys.stdin.buffer

或sys.stdout.buffer

• 行為就像是以open()函式開啟的二進位模式檔案物件

Page 22: open() 與 io 模組

• 可以改變標準輸入或輸出的來源

Page 23: open() 與 io 模組

• 將一個自行開啟的檔案物件,指定給 sys.stdout,就可以利用 print() 來寫

出資料至檔案

• 內建的 print() 函式本身,就有一個 file 參數可以達到這樣的需求

Page 24: open() 與 io 模組

• 可以使用 >將程式執行時的標準輸出訊息,導向至指定的檔案,或者使用 >> 附加訊息

• 標準錯誤的輸出不能使用 >或 >> 重新導向

至檔案

Page 25: open() 與 io 模組

認識檔案描述器

• open() 函式的 file 參數,除了接受字串

指定檔案的路徑外,還可指定檔案描述器

• 檔案描述器會是個整數值,對應至目前程式已開啟的檔案

• 標準輸入通常使用檔案描述器 0,標準輸出是 1,標準錯誤是 2,進一步開啟的檔案則會是 3、4、5 等數字

Page 26: open() 與 io 模組

• 對於檔案物件,可以使用 fileno() 方法

來取得檔案描述器

Page 27: open() 與 io 模組

• 如果指定 open() 的第一個參數為0 會如何

呢?

Page 28: open() 與 io 模組

• 若能取得一個對應至系統上已開啟的檔案描述器,就有機會使用 open() 來包裹成

為檔案物件,以利用檔案物件的高階行為

Page 29: open() 與 io 模組

• open() 函式的 closed 參數預設值是 True

–這表示若 open()時 file 指定了一個檔案

描述器,在檔案物件呼叫 close()方法而關

閉時,被指定的檔案描述器也會一併關閉

–當指定為 False 時,就不會關閉被指定的檔

案描述器

Page 30: open() 與 io 模組

• open() 還有個 opener 可以用來指定一個函式,該函式必須有兩個參數

–第一個參數會傳入 open() 函式被指定的檔案路徑

–第二個參數會是 open() 函式依 mode 而計算出來的 flags 值,函式最後必須傳回一個檔案描述器

–open() 函式基於該檔案描述器建立檔案物件,以便進行檔案操作。

Page 31: open() 與 io 模組
Page 32: open() 與 io 模組

認識 io 模組

• open() 函式實際上是個工廠函式

• 若想進一步掌握檔案物件的操作,就得認識 io 模組

Page 33: open() 與 io 模組

• 檔案物件大致上分為三個主要類型

–文字(Text)I/O

–二進位(Binary)I/O

–原始(Raw)I/O

Page 34: open() 與 io 模組
Page 35: open() 與 io 模組
Page 36: open() 與 io 模組

• 原始 I/O 是無緩衝低階操作,少直接使用,常作為文字 I/O 或二進位 I/O 底層操作

Page 37: open() 與 io 模組

• TextIOWrapper 也是個包裹器,可以包裹 BufferedIOBase,以便將二進位資料

依指定的文字編碼進行轉換

Page 38: open() 與 io 模組

• 如果資料的讀取來源或寫入目的地,並不是個檔案,而想要是記憶體中某個物件,那麼可以使用 BytesIO 或 StringIO

Page 39: open() 與 io 模組

• 通常使用 BytesIO 時,最後會使用 getvalue() 方法來取得寫入的資料

Page 40: open() 與 io 模組

• 若想讀寫的是文字資料,可以使用 StringIO