文件I/O是Python中最重要的技術之一,在Python中對文件進行I/O操作是非常簡單的。
1. 打開文件
使用 open
函數來打開文件,語法如下:
open(name[, mode[, buffering]])
1.1 文件模式
open
函數除了必須提供的文件名參數外,其實還有一個 mode
的模式參數,如果沒有指定參數值的話,它的默認值是: r
。mode
參數的可選值如下:
1 'r' 讀模式 2 'w' 寫模式 3 'a' 追加模式 4 'b' 二進制模式(可添加到其他模式使用) 5 '+' 讀/寫模式(可添加其他模式使用)
1.2 緩沖
open 函數的第三個參數( buffering
),表示文件的緩沖,當緩沖區大於0時(等於0時無緩沖,所有的讀寫操作都直接針對硬盤),Python會將文件內容存放到緩沖區(內存中),從而是程序運行的的更快,這時,只有使用 flush
或者 close
時才會將緩沖區中的數據更新到硬盤中。
2. 文件的讀和寫
文件流最重要的功能就是讀取和寫入數據。對應於文件對象來說就是: read
和 write
方法。
三種標准的流:
標准文件對象包括 sys 模塊的:stdin,stdout 以及 stderr 都是類文件對象,該對象實現了UNIX標准的I/O機制(Windows 中也能使用)。
2.1 寫入文件
每次調用 f.write(string)
時,所提供的string參數值,會被寫入到文件中(但是調用這個方法之前文本的內容會被覆寫掉)。如下:
1 f = open(r'C:\text.txt','w') 2 f.write('hello,') 3 f.write('world') 4 f.close()
寫入更多內容
通過使用 f.writelines
方法,將一個字符串列表(任何序列或可迭代對象)作為參數,即可把這些內容寫入到文件(流)中。
注意:使用
writelines
方法不會增加新行,寫入流的方法中也沒有對應的writeline
方法,需要自己增加新行。(不同平台使用不同的換行符,如 Mac 使用r
,Windows 使用\r\n
。可以通過os.linesep
來獲取)。
更新文件內容
寫入了一些文件內容后,這些內容不一定能夠理解體現在文件中,因為數據可能被緩存在內存中了,知道關閉時才會被真正寫入到文件,如果想要在文件關閉前立即對文件內容進行更新,可以考慮調用文件對象的
flush
方法(該方法不允許其他程序使用該文件的同時訪問文件)。
2.2 讀取文件
調用 f.read([charCount])
讀取文件內容,根據可選的讀取字符數讀取文件內容,如果不指定參數則讀取還沒有被讀取過的內容,如下:
1 # -- coding: utf-8 -- 2 f = open(r'C:\text.txt','r') # mode = 'r',默認值 3 4 # 讀取4個字符 5 print f.read(4) # hell 6 print f.read() # o,world 7 f.close()
2.3 關閉文件
當我們使用完文件對象后應該及時把它關閉掉,以節省系統資源,或者保證文件完整性。這時候我們可以使用 try/finally
語句來完成,通過在 finally
語句中調用 f.close()
方法,確保文件會被關閉:
1 # -- coding: utf-8 -- 2 # 打開文件 3 f = open(r'C:\text.txt','w') 4 5 try: 6 # 寫入文件 7 f.write('hello,') 8 f.write('world') 9 finally: 10 # 關閉文件 11 f.close()
除了使用 finally
語句來關閉文件,還可以使用 Python 2.5 之后引入的新語法—— with語句
來關閉文件:
1 # -- coding: utf-8 -- 2 3 # with 語句體中的代碼執行結束后,文件會被自動關閉(即使發生了異常) 4 with open(r'C:\text.txt','w') as f: 5 f.write('hello,') 6 f.write('world')
讀取更多內容
f.read([charCount])
是逐字節讀取的,我們還可以使用更簡便的方法: f.readline([charCount])
,如果不適用任何參數直接讀取單獨的一行(從當前位置開始,知道一個換行符為止),如果使用一個非負數的整數作為參數,表示可以讀取字符的最大值。f.readlines()
方法可以讀取一個文件中所有的行,並將其作為列表返回。
3. 迭代文件內容
對文件內容進行迭代以及執行一些重復的操作,是最常見的文件操作之一。
3.1 按字節處理
最常見的對文件內容進行迭代的方式是在 while
循環中使用 read
方法:
1 f = open(r'C:\text.txt','r') 2 3 char = f.read(1) 4 while char: 5 print char 6 char = f.read(1) 7 f.close()
當文件達到末尾是,read
方法會返回一個空字符串,則 char
是 false
。上面的示例還有可以使用 while true/break
語句實現更簡潔的寫法:
1 # -- coding: utf-8 -- 2 f = open(r'C:\text.txt','r') 3 4 while True: 5 line = f.read(1) 6 if not line:break 7 print line 8 f.close()
3.2 按行操作
按行讀取的方式和按字節的方式類似,只需要將 read
方法換成了 readline
方法即可:
1 # -- coding: utf-8 -- 2 f = open(r'C:\text.txt','r') 3 4 while True: 5 line = f.readline() 6 if not line:break 7 print line 8 f.close()
3.3 一次讀取所有內容
對於一個不是很大的文件,我們可以使用不帶參數的 read
方法一次性的讀取整個文件(當作一個字符串),或者使用 readlines
方法把文件讀入一個字符串列表中,列表中每個字符串就是一行。下面使用 read
方法讀取所有內容:
1 f = open(r'C:\text.txt','r') 2 3 for char in f.read(): 4 print char 5 f.close()
使用readlines
方法讀取所有內容:
1 f = open(r'C:\text.txt','r') 2 3 for line in f.readlines(): 4 print line 5 f.close()
3.4 按需加載並迭代
對文件內容進行按需加載,而不是一次性的將其從讀到內存的中好處之一就是可以按需加載,節省系統資源,特別是對一些超大的文件來說更是如此。如果對大文件進行迭代操作可以考慮下面的兩種方式:
使用fileinput實現惰性迭代
需要對一個非常大的文件進行迭代時,使用 readlines
會占用過多的內存,這時候除了可以用 while
循環和 readline
來替代,還可以通過使用 for
循環和 fileinput
模塊來實現懶惰迭代——即按需迭代:
1 import fileinput 2 3 for line in fileinput.input(r'C:\text.txt'): 4 print line
使用文件迭代器
從Python 2.2 開始,文件對象是可迭代的,這表示可以直接在 for
循環對它們進行迭代操作:
1 f = open(r'C:\text.txt') 2 for line in f: 3 print line 4 f.close()