本文主要討論一下文件的三種可讀可寫模式的特色及互相之間的區別,以及可否實現修改文件的操做
因爲前文已經討論過編碼的事情了,因此這裏再也不研究編碼,全部打開操做默認都是utf-8編碼(Linux系統下)python
既然r+既能讀又能寫,那麼可否實如今r+模式下進行文件的修改呢?答案是確定的!,可是,有一點你須要注意,除非你知道在確切的位置修改確切的內容,不然每每不會獲得你指望的結果。舉個例子以下:
咱們有這樣一個文本「十步殺一人,千里不留行」
假設有這樣一個需求,把「十步殺一人」改爲「十步殺一個土匪」,初步設想是:用read(4)讀取到漢字「一」,而後寫入漢字「個土匪」:編碼
with open('job', mode='r+') as f: print('先讀取四個字符:',f.read(4)) print('讀取後的指針位置:',f.tell()) f.write('個土匪') f.seek(0) print(f.read()) 輸出爲: 先讀取四個字符: 十步殺一 讀取後的指針位置: 12 十步殺一人,千里不留行個土匪
從結果能夠看到,使用read(4)指針確實移動到了指定的位置,可是寫入的時候卻沒有按照設想,而是跑到了文件的末尾。這個緣由涉及到一個叫「CHUNK」的東西,俺滴老師沒教,我也很差深說,等深刻理解它後再和大家講哈😅😅😅指針
那麼咱們只說解決辦法,能夠用seek()手動定位指針,讓它處在12的位置,而後再寫入:code
with open('job', mode='r+') as f: print('先讀取四個字符:',f.read(4)) print('讀取後的指針位置:',f.tell()) f.seek(f.tell()) f.write('個土匪') f.seek(0) print(f.read()) 輸出: 先讀取四個字符: 十步殺一 讀取後的指針位置: 12 十步殺一個土匪裏不留行
從結果能夠看出,它確實是把人字改爲了「個土匪」,但是它卻把後面的字給覆蓋了,這徹底不是咱們想要的結果,那麼爲何呢?
緣由就是:當文件寫入磁盤後,磁盤會分出一塊空間(實際上應該叫多個存儲元的集合,具體請參考我另一篇文章),這塊空間是固定的,當你定位指針修改已經存在的內容時,相鄰的後面的內容並不會給你要寫入的內容「讓地方」,也就是說你能夠對它進行覆蓋操做,可是你不能讓後面的內容挪地方(這麼說直白不?應該能明白吧。), 所以,雖然咱們想要修改的是人這個字,可是因爲你寫入了「個土匪」三個字,因此後面的內容被覆蓋了,變成了「十步殺一個土匪裏不留行」。utf-8
w+,也就是寫讀操做,仍然對文件libai2操做,需求仍是上例的需求it
with open('libai2','w+') as f: content = f.read(25)#讀取25個字符,這其中包括24箇中文漢字或符號 和 一個換行符 print('讀取操做後的指針位置:',f.tell())#指針處在0,那麼意味着文件內容是空的 f.write('五')#而後咱們寫入中文漢字:「五」,期待能覆蓋掉原來的「十」 print('寫入操做後的指針位置:',f.tell())#結果發現指針在3字節的位置,也就是一個漢字五的後面 f.seek(0) print(f.read())
讀取操做後的指針位置: 0 寫入操做後的指針位置: 3 五
咱們能夠看到整個文件的內容消失了,只有一個漢字「五」
這是由於w開頭的模式會先進行判斷,若是文件已存在則打開文件,而且清空文件內容。若是該文件不存在,則建立新文件。
因此當使用w+這種模式打開文件的那一刻,這個文件本來的內容就已經消失了。class
咱們在後臺重新建立了一個libai3文件,裏面仍是隻包含那兩句詩後臺
with open('libai3','a+') as f: print('初始指針位置',f.tell()) #初始指針位置是146,48個漢字或字符 加2個換行符,48*3+2=146 #由此能夠看出,初始文件指針處在文件末尾位置 f.seek(73) #咱們把指針調整到73字節的位置,也就是漢字「十」的前面 print('調整指針在73字節的位置:',f.tell()) f.write('五')#而後咱們寫入漢字「五」 f.seek(0) #調整指針到文件頭部位置 print(f.read()) #輸出文件看看發生了什麼
初始指針位置 146 調整指針在73字節的位置: 73 趙客縵胡纓,吳鉤霜雪明。銀鞍照白馬,颯沓如流星。 十步殺一人,千里不留行。事了拂衣去,深藏身與名。 五
咱們發現漢字「五」仍是被寫在了文件末尾總結
w+和a+沒法完成文件的修改操做,r+能夠實現修改的操做,可是結果每每和咱們預期的不太同樣,固然,除非你知道要把確切的內容換成確切的新內容,不過感受這個應用價值不大吧?集合