這里講的文件讀寫窍奋,是由 Python 提供的最基礎(chǔ)的文件讀寫荐健,主要是對文本文件和二進(jìn)制文件的讀寫。
如果想要操作 excel琳袄, csv江场,ymal,xml窖逗,json 等特定格式的文件址否,需要特定的庫進(jìn)行處理。
文本文件:在 windows 上但凡能用記事本正常打開的文件都是文本文件碎紊,比如 .txt佑附,.log用含,.py 等;
二進(jìn)制文件:可執(zhí)行文件帮匾,圖片文件,視頻文件等痴鳄。
Python 提供了 open()
函數(shù)用于文件讀寫瘟斜。
f = open(文件路徑,讀寫方式)
open() 函數(shù)主要參數(shù)有兩個(gè):
文件路徑:包含文件名的路徑痪寻,如 D:\nemo\io.txt螺句;
讀寫方式:指定打開文件的模式,比如只讀('r')橡类,只寫('w')蛇尚,追加('a')等。
open() 函數(shù)會(huì)根據(jù)讀寫方式將文件加載到內(nèi)存中顾画,返回一個(gè)文件對象取劫。f 變量就是用來保存這個(gè)對象的。所有后續(xù)就可以使用 f 變量對該文件進(jìn)行讀寫操作研侣。
所有情況下文件操作主要包含如下三個(gè)步驟:
- 調(diào)用 open() 函數(shù)打開文件
- 進(jìn)行文件操作谱邪,讀、寫庶诡、追加等
- 關(guān)閉文件
在使用 open() 函數(shù)的時(shí)候惦银,必須要根據(jù)需要使用對應(yīng)的讀寫方式:
讀寫方式 | 操作 | 說明 |
---|---|---|
r | 只讀 | 以只讀方式打開,文件不存在會(huì)報(bào)錯(cuò)末誓。默認(rèn)方式扯俱,可以不用寫。 |
w | 只寫 | 不能讀取喇澡,只能寫入迅栅。 文件不存在就創(chuàng)建,文件存在則覆蓋(清空原來的內(nèi)容)撩幽。 |
a | 追加 | 不能讀取库继,只能寫入,在文件的末尾追加窜醉。 文件不存在就創(chuàng)建宪萄,文件存在則在末尾追加。 |
x | 新建 | 文件存在則會(huì)報(bào)錯(cuò)榨惰,文件不存在就新建并支持寫入拜英。 比 w 方式安全,w 方式會(huì)覆蓋原有內(nèi)容琅催,誤操作可能造成數(shù)據(jù)丟失居凶。 |
rb | 二進(jìn)制只讀 | 同 r 虫给,只是操作對象為二進(jìn)制文件,使用 bytes 類型讀侠碧。 |
wb | 二進(jìn)制只寫 | 同 w抹估,寫入類型必須是 bytes 類型 |
ab | 二進(jìn)制追加 | 同 a,寫入類型必須是 bytes 類型 |
+ | 可讀寫 | r+弄兜,w+药蜻,a+,rb+替饿,wb+语泽,ab+,帶加號(hào)代表既可寫也可讀 |
文件操作
我們先準(zhǔn)備一個(gè)文件:
這個(gè)文件放在
D:\data\pythonIO
中视卢,文件名為test_read.txt
踱卵。
注意,很多人 windows 沒有開啟擴(kuò)展名据过⊥锷埃看到的文件名沒有
.txt
后綴,那么一定要開啟绳锅,文件名+后綴名
才是完整的文件名班利。如何開啟?點(diǎn)我榨呆!
好了罗标,文件已經(jīng)準(zhǔn)備好,接下來就使用 Python 代碼進(jìn)行文件操作了积蜻。
文件讀取
我們先以只讀方式打開闯割,讀寫方式為r
。
f = open(r'D:\data\pythonIO\test_read.txt', 'r')
# 默認(rèn)是文本只讀竿拆,所以'r'其實(shí)可以不寫
data = f.read() # 讀取文件所有內(nèi)容
f.close() # 文件打開必須要關(guān)閉
print(data)
'''
Python教程
0基礎(chǔ)入門切忌追求大而全
快速掌握必要基礎(chǔ)語法
再進(jìn)行有一定目的和趣味的練習(xí)
才能避免從入門到放棄的悲劇
'''
上例中宙拉,我們使用了只讀r
的方式打開了文件。
Python 中提供的文件讀取方法如下:
f.read():
一次性讀取文件中所有內(nèi)容丙笋。
read() 方法有一個(gè)默認(rèn)參數(shù) size惫企,用來指定讀取的字符數(shù)晃虫。當(dāng)文件過大時(shí),一次性讀取內(nèi)存扛不住,就可以使用 read(size) 來循環(huán)讀取豫缨。
還是以上面的例子中的文件為例:
f = open(r'D:\data\pythonIO\test_read.txt', )
print(f.read(8)) # 讀取5個(gè)字符
# Python教程
f.close()
注意缩举,size 在文本讀取時(shí)表示字符個(gè)數(shù)洁奈。而以二進(jìn)制方式打開時(shí)串慰,size 表示字節(jié)數(shù)。
f.readline()
一行行讀取,遇到 \n 或 \r\n 等換行符時(shí)停止钉答。換行符础芍,我們在文件中看不到,一般只要你通過回車換行数尿,就會(huì)自動(dòng)生成一個(gè)換行符仑性。
f = open(r'D:\data\pythonIO\test_read.txt', )
print(f.readline()) # 讀取第一行內(nèi)容
# Python教程
print(f.readline()) # 再次調(diào)用,讀取第二行
# 0基礎(chǔ)入門切忌追求大而全
f.close()
f.readlines()
按行讀取所有內(nèi)容右蹦,返回一個(gè)列表虏缸。文件中的每行內(nèi)容為列表的一個(gè)元素。
f = open(r'D:\data\pythonIO\test_read.txt', )
print(f.readlines()) # 讀取第一行內(nèi)容
# ['Python教程\n', '0基礎(chǔ)入門切忌追求大而全\n', '快速掌握必要基礎(chǔ)語法\n', '再進(jìn)行有一定目的和趣味的練習(xí)\n', '才能避免從入門到放棄的悲劇\n']
f.close()
這種方式讀出為列表嫩实,所以可以按照列表的方式靈活處理讀取的內(nèi)容。但是同樣也要注意的窥岩,這種方法會(huì)讀取整個(gè)文件內(nèi)容甲献,如果文件過大則可能會(huì)占用大量的內(nèi)存。
文件寫入
文件寫入有三種方式:
w:覆蓋寫入颂翼,當(dāng)文件存在時(shí)會(huì)覆蓋文件晃洒,文件不存在則創(chuàng)建
a:追加寫入,當(dāng)文件存在時(shí)在末尾寫入朦乏,文件不存在則創(chuàng)建
x:新建文件球及,當(dāng)文件存在時(shí)報(bào)錯(cuò),文件不存在則創(chuàng)建
以上呻疹,讀寫方式不同吃引,導(dǎo)致會(huì)產(chǎn)生不同的結(jié)果。如果是 w 方式的話 刽锤,一定要注意文件覆蓋镊尺。
對于文件寫入,主要的方法如下:
f.write()
將內(nèi)容寫入文件并思,并返回寫入的字符數(shù)庐氮。但是要注意,寫入過程都是在內(nèi)存中進(jìn)行的宋彼,并不會(huì)馬上體現(xiàn)在文件中弄砍,直到 f.close() 的時(shí)候,才會(huì)將內(nèi)存中的內(nèi)容實(shí)際寫入文件输涕。
f = open(r'D:\data\pythonIO\test_read.txt', 'w+')
f.write('極簡教程')
# 4
f.close()
你會(huì)發(fā)現(xiàn)原來的內(nèi)容被修改了音婶。
文件指針
文件讀寫過程中莱坎,存在文件指針的概念桃熄,當(dāng)你讀取一部分內(nèi)容后,指針位置就會(huì)后移,這樣就只能讀取后面的內(nèi)容瞳收。
如果你想讀取已讀取過的內(nèi)容怎么辦呢碉京?也不是沒有辦法,Python 提供了seek
螟深,tell
兩個(gè)方法來處理指針谐宙。
f.tell()
獲取文件指針當(dāng)前所在的位置。不過要注意的是界弧,它是從文件開頭算起凡蜻,到當(dāng)前位置的字節(jié)數(shù)。
f = open(r'D:\data\pythonIO\test_read.txt', 'r')
print(f.read(8)) # 讀取8個(gè)字符
# Python教程
print(f.tell()) # 打印當(dāng)前位置
# 10
f.close()
讀取了8個(gè)字符垢箕,但是返回的位置是10划栓。因?yàn)槲覀兊奈募杏袧h字,一個(gè)漢字是兩個(gè)字節(jié)条获。我們讀出來的 8 個(gè)字符中有兩個(gè)漢字忠荞,所以當(dāng)前的位置是 10(第 10 個(gè)字節(jié))。
f.seek()
通過 f.seek() 方法可以修改指針的位置帅掘。這個(gè)方法有兩個(gè)參數(shù)委煤,f.seek(target, whence)。target 用于指定修改指針的位置修档,whence用于指定修改指針位置時(shí)從哪里開始計(jì)算(0碧绞,表示從文件開始,1吱窝,表示從當(dāng)前位置讥邻,2,表示從文件末尾院峡。默認(rèn)為0)
注意计维,如果文件不是以二進(jìn)制方式打開,whence 只能取 0撕予,也就是只能從文件開始計(jì)算偏移量鲫惶。
f = open(r'D:\data\pythonIO\test_read.txt', 'r')
f.read(8) # 讀取8個(gè)字符
# Python教程
f.tell() # 打印當(dāng)前位置
# 10
f.seek(0) # 移到文件開頭
# 0
f.seek(5) # 移到從文件開始算第5個(gè)字節(jié)位置
# 5
f.seek(-3, 1) # 從當(dāng)前位置向前移動(dòng)3個(gè)字節(jié),會(huì)報(bào)錯(cuò)
# io.UnsupportedOperation: can't do nonzero end-relative seeks
f.close()
使用rb方式打開实抡,才能使用 whence 參數(shù)的另外兩個(gè)值欠母,也就是從當(dāng)前位置或者文件末尾計(jì)算。因?yàn)橐粋€(gè)漢字是兩個(gè)字符吆寨,你如果按字節(jié)移動(dòng)的時(shí)候就無法正常讀取了赏淌。
比如某個(gè)漢字占了5和6位字節(jié)(一個(gè)漢字占兩個(gè)字節(jié)),這時(shí)候你移到6啄清,那怎么讀呢六水?讀這個(gè)漢字的一半?
f = open(r'D:\data\pythonIO\test_read.txt', 'rb')
f.read(8) # 讀取8個(gè)字節(jié)
# b'Python\xbd\xcc'
f.tell() # 打印當(dāng)前位置
# 8
f.seek(-5,1) # 從當(dāng)前位置向前移動(dòng)5個(gè)字節(jié)
# 3
f.seek(-5, 2) # 從文件末尾向前移動(dòng)5個(gè)字節(jié)
# 112
f.seek(0, 2) # 移動(dòng)到文件末尾
# 117
f.close()