1. 讀文件
打開一個文件用 open()
方法(open()返回一個文件對象域那,它是可迭代的):
f = open('test.txt', 'r') # r表示是文本文件软驰,rb是二進(jìn)制文件(這個mode參數(shù)默認(rèn)值就是r)
f.close() # 文件使用完畢后必須關(guān)閉笑跛,因為文件對象會占用操作系統(tǒng)的資源,并且操作系統(tǒng)同一時間能打開的文件數(shù)量也是有限的
# 但是每次都這么寫實在太繁瑣,所以,Python引入了with語句來自動幫我們調(diào)用close()方法:
with open('/path/to/file', 'r') as f:
print(f.read())
??python 文件對象提供了三個“讀”方法: read()
粘捎、readline()
和 readlines()
。每種方法可以接受一個變量以限制每次讀取的數(shù)據(jù)量危彩。
注意:這三種方法是把每行末尾的 \n
也讀進(jìn)來了攒磨,它并不會默認(rèn)的把'\n'去掉,需要我們手動去掉汤徽。
- read() 每次讀取整個文件娩缰,它通常用于將文件內(nèi)容放到一個字符串變量中。如果文件大于可用內(nèi)存谒府,為了保險起見漆羔,可以反復(fù)調(diào)用read(size)方法,每次最多讀取size個字節(jié)的內(nèi)容狱掂。
- readlines() 之間的差異是后者一次讀取整個文件,象 .read() 一樣亲轨。.readlines() 自動將文件內(nèi)容分析成一個行的列表趋惨。
- readline() 每次只讀取一行,通常比readlines() 慢得多惦蚊。僅當(dāng)沒有足夠內(nèi)存可以一次讀取整個文件時器虾,才應(yīng)該使用 readline()讯嫂。
2. 寫文件
f = open('test.txt', 'w') # 若是'wb'就表示寫二進(jìn)制文件
f.write('Hello, world!')
f.close()
注意: w
這個模式是這樣:如果沒有這個文件,就創(chuàng)建一個兆沙;如果有欧芽,那么就會先把原文件的內(nèi)容清空再寫入新的東西。所以若不想清空原來的內(nèi)容而是直接在后面追加新的內(nèi)容葛圃,就用 a
這個模式千扔。
??我們可以反復(fù)調(diào)用 write() 來寫入文件,但是務(wù)必要調(diào)用 f.close()
來關(guān)閉文件库正。當(dāng)我們寫文件時曲楚,操作系統(tǒng)往往不會立刻把數(shù)據(jù)寫入磁盤,而是放到內(nèi)存緩存起來褥符,空閑的時候再慢慢寫入龙誊。只有調(diào)用 close() 方法時,操作系統(tǒng)才保證把沒有寫入的數(shù)據(jù)全部寫入磁盤喷楣。忘記調(diào)用 close() 的后果是數(shù)據(jù)可能只寫了一部分到磁盤趟大,剩下的丟失了。所以铣焊,還是用 with
語句來得保險:
with open('test.txt', 'w') as f:
f.write('Hello, world!')
python文件對象提供了兩個“寫”方法: write()
和 writelines()
逊朽。
- write()方法和read()、readline()方法對應(yīng)粗截,是將字符串寫入到文件中惋耙。
- writelines()方法和readlines()方法對應(yīng),也是針對列表的操作熊昌。它接收一個字符串列表作為參數(shù)绽榛,將他們寫入到文件中,換行符不會自動的加入婿屹,因此需要顯式的加入換行符灭美。
3. 關(guān)于open()的mode參數(shù):
-
r
:讀 -
w
:寫 -
a
:追加 -
r+
== r+w(可讀可寫,文件若不存在就報錯(IOError)) -
w+
== w+r(可讀可寫昂利,文件若不存在就創(chuàng)建) -
a+
== a+r(可追加可寫届腐,文件若不存在就創(chuàng)建) - 對應(yīng)的,如果是二進(jìn)制文件蜂奸,就都加一個b就好啦:
rb
wb
ab
rb+
wb+
ab+
4. 字符編碼
要讀取非UTF-8編碼的文本文件犁苏,需要給open()函數(shù)傳入encoding參數(shù),例如扩所,讀取GBK編碼的文件:
f = open('test.txt', 'r', encoding='gbk')
f.read()
遇到有些編碼不規(guī)范的文件围详,你可能會遇到UnicodeDecodeError,因為在文本文件中可能夾雜了一些非法編碼的字符。遇到這種情況助赞,open()函數(shù)還接收一個errors參數(shù)买羞,表示如果遇到編碼錯誤后如何處理。最簡單的方式是直接忽略:
f = open('test.txt', 'r', encoding='gbk', errors='ignore')
5. 讀取大文件
??最近處理文本文檔時(文件約 28GB 大斜⑹场)畜普,出現(xiàn)memoryError錯誤和文件讀取太慢的問題,處理大文件是很容易想到的就是將大文件分割成若干小文件處理群叶,處理完每個小文件后釋放該部分內(nèi)存吃挑。這里用了 iter
& yield
:
5.1 Read In Chunks
def read_in_chunks(filePath, chunk_size=1024*1024):
"""
Lazy function (generator) to read a file piece by piece.
Default chunk size: 1M
You can set your own chunk size
"""
try:
file_object = open(filePath)
while True:
chunk_data = file_object.read(chunk_size)
if not chunk_data:
break
yield chunk_data
finally:
if file_object:
f.close()
if __name__ == "__main__":
filePath = './path/filename'
for chunk in read_in_chunks(filePath):
process(chunk) # <do something with chunk>
5.2 Using with open()
對可迭代對象 f,進(jìn)行迭代遍歷:for line in f盖呼,會自動地使用緩沖IO(buffered IO)以及內(nèi)存管理儒鹿,而不必?fù)?dān)心任何大文件的問題。
with open(filename, 'rb') as f:
for line in f:
<do something with the line>