1. 打開文件
使用open打開文件后一定要記得調(diào)用文件對象的close()方法。比如可以用try/finally語句來確保最后能關(guān)閉文件。
fp = open(name, mode, buffering)
入口參數(shù):
name:文件名
mode:選項、字符串
buffering:是否緩沖(0=不緩沖,1=緩沖,>1的int數(shù)=緩沖區(qū)大小)
返回值:文件對象
方法一:復(fù)雜寫法
try:
f = open('xxx')
except:
print 'fail to open'
exit(-1)
try:
do something
except:
do something
finally:
f.close()
方法二:簡單寫法
with open('thefile.txt') as file_object:
all_the_text = file_object.read( )
這種方式,系統(tǒng)會自動幫你關(guān)閉文件
分析:
不安全寫法:
file_object = open('thefile.txt')
try:
all_the_text = file_object.read( )
finally:
file_object.close( )
注:這種方式可能會出錯,當(dāng)文件沒有打開時,程序會出錯
錯誤寫法:
try:
file_object = open('thefile.txt')
all_the_text = file_object.read( )
except:
do something
finally:
file_object.close( )
注:這種方式看似正常,但是有很大隱患,因?yàn)榘裲pen語句放在try塊里,當(dāng)打開文件出現(xiàn)異常時,文件對象file_object無法執(zhí)行close()方法。
2. 讀文件
讀文本文件
input = open('data', 'r') # 第二個參數(shù)默認(rèn)為r, 可不傳
input = open('data', 'rb') # 讀二進(jìn)制文件
讀取所有內(nèi)容
with open('thefile.txt') as file_object:
all_the_text = file_object.read( )
讀固定字節(jié)
with open('abinfile', 'rb') as file_object:
try:
while True:
chunk = file_object.read(100)
if not chunk:
break
do_something_with(chunk)
except:
do ...
讀每行
list_of_all_the_lines = file_object.readlines( )
如果文件是文本文件,還可以直接遍歷文件對象獲取每行:
for line in file_object:
process line
size為讀取的長度,以byte為單位
F.read([size])
F.readline([size])
讀一行,如果定義了size,有可能返回的只是一行的一部分
F.readlines([size])
把文件每一行作為一個list的一個成員,并返回這個list。
其實(shí)它的內(nèi)部是通過循環(huán)調(diào)用readline()來實(shí)現(xiàn)的。如果提供size參數(shù),size是表示讀取內(nèi)容的總長,也就是說可能只讀到文件的一部分。
3. 寫文件
output = open('data', 'w') # 寫文本文件
output = open('data', 'wb') # 寫二進(jìn)制文件
output = open('data', 'a') # 追加寫文件
一次性寫入數(shù)據(jù)
file_object.write(all_the_text)
寫入多行
file_object.writelines(list_of_text_strings)
注意:調(diào)用writelines寫入多行在性能上會比使用write一次性寫入要高。
在處理日志文件的時候,常常會遇到這樣的情況:日志文件巨大,不可能一次性把整個文件讀入到內(nèi)存中進(jìn)行處理,例如需要在一臺物理內(nèi)存為 2GB 的機(jī)器上處理一個 2GB 的日志文件,我們可能希望每次只處理其中 200MB 的內(nèi)容。
在 Python 中,內(nèi)置的 File 對象直接提供了一個 readlines(sizehint) 函數(shù)來完成這樣的事情。以下面的代碼為例:
file = open('test.log', 'r')
sizehint = 209715200 # 200M
position = 0
lines = file.readlines(sizehint)
while not file.tell() - position < 0:
position = file.tell()
lines = file.readlines(sizehint)
每次調(diào)用 readlines(sizehint) 函數(shù),會返回大約 200MB 的數(shù)據(jù),而且所返回的必然都是完整的行數(shù)據(jù),大多數(shù)情況下,返回的數(shù)據(jù)的字節(jié)數(shù)會稍微比 sizehint 指定的值大一點(diǎn)(除最后一次調(diào)用 readlines(sizehint) 函數(shù)的時候)。通常情況下,Python 會自動將用戶指定的 sizehint 的值調(diào)整成內(nèi)部緩存大小的整數(shù)倍。
4. 文件其他操作
函數(shù) | 說明 |
---|---|
F.flush() | 把緩沖區(qū)的內(nèi)容寫入硬盤 |
F.fileno() | 返回一個長整型的”文件標(biāo)簽“ |
F.isatty() | 文件是否是一個終端設(shè)備文件(unix系統(tǒng)中的) |
F.tell() | 返回文件操作標(biāo)記的當(dāng)前位置,以文件的開頭為原點(diǎn) |
F.next() | 返回下一行,并將文件操作標(biāo)記位移到下一行。把一個file用于for ... in file這樣的語句時,就是調(diào)用next()函數(shù)來實(shí)現(xiàn)遍歷的。 |
F.seek(offset[,whence]) | 將文件打操作標(biāo)記移到offset的位置。這個offset一般是相對于文件的開頭來計算的,一般為正數(shù)。但如果提供了whence參數(shù)就不一定了,whence可以為0表示從頭開始計算,1表示以當(dāng)前位置為原點(diǎn)計算。2表示以文件末尾為原點(diǎn)進(jìn)行計算。需要注意,如果文件以a或a+的模式打開,每次進(jìn)行寫操作時,文件操作標(biāo)記會自動返回到文件末尾。 |
F.truncate([size]) | 把文件裁成規(guī)定的大小,默認(rèn)的是裁到當(dāng)前文件操作標(biāo)記的位置。如果size比文件的大小還要大,依據(jù)系統(tǒng)的不同可能是不改變文件,也可能是用0把文件補(bǔ)到相應(yīng)的大小,也可能是以一些隨機(jī)的內(nèi)容加上去。 |
5. 模式
模式 | 說明 |
---|---|
"r" | 以讀方式打開,只能讀文件 , 如果文件不存在,會發(fā)生異常 |
"r+" | 以可讀寫方式打開文件,該文件必須存在,否則會發(fā)生異常 |
"w" | # 以寫方式打開,只能寫文件, 如果文件不存在,創(chuàng)建該文件,如果文件已存在,先清空,再打開文件 |
"w+" | 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內(nèi)容會消失。若文件不存在則建立該文件。 |
"a" | 以附加方式打開可寫的文件,文件不存在會自動創(chuàng)建文件。 |
"a+" | 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數(shù)據(jù)會被加到文件尾后,即文件原先的內(nèi)容會被保留。 (原來的EOF符不保留) |
"rb" | 以二進(jìn)制讀方式打開,只能讀文件 , 如果文件不存在,會發(fā)生異常 |
"wb" | 以二進(jìn)制寫方式打開,只能寫文件, 如果文件不存在,創(chuàng)建該文件, 如果文件已存在,先清空,再打開文件 |
"rt" | 以文本讀方式打開,只能讀文件 , 如果文件不存在,會發(fā)生異常 |
"wt" | 以文本寫方式打開,只能寫文件, 如果文件不存在,創(chuàng)建該文件,如果文件已存在,先清空,再打開文件 |
"rb+" | 以二進(jìn)制讀方式打開,可以讀、寫文件 , 如果文件不存在,會發(fā)生異常 |
"wb+" | 以二進(jìn)制寫方式打開,可以讀、寫文件, 如果文件不存在,創(chuàng)建該文件,如果文件已存在,先清空,再打開文件 |