檔案操作
初始檔案操作
使用Python來讀寫檔案是非常簡單的操作,我們使用open()函數來打開一個檔案,擷取到檔案句柄,然後通過檔案句柄就可以進行各種各樣的操作了
根據打開方式的不同能夠執行的操作會有相應的差異.
打開檔案的方式:
r,w,a
r+,w+,a+
rb,wb,ab
r+b,w+b,a+b
預設使用的是r(隻讀模式)
隻讀操作(r/rb)
f = open('護士少婦蘿莉',mode='r',encoding='utf-8')
content = f.read()
print(content)
f.close()
結果:
标題很好
上邊的内容open()函數打開護士少婦蘿莉的檔案,然後指派到一個句柄中,open函數中的mode是對這個檔案操作是的一種模式
encoding這個是指定檔案中内容的編碼集,接下來的操作就完全通過句柄來操作
f = open('護士少婦蘿莉',mode='rb')
content = f.read()
print(content)
f.close()
結果:
b'\xe6\xa0\x87\xe9\xa2\x98\xe5\xbe\x88\xe5\xa5\xbd'
rb 讀出來的資料是bytes類型,在rb模式下,不能encoding字元集
rb的作用:在讀取非文本檔案的時候,比如要讀取mp3,圖像,視訊等資訊的時候就需要用到rb,因為這種資料是沒辦法直接顯示出來的
在後面我們檔案上傳下載下傳的時候還會用到.
絕對路徑和相對路徑
1.絕對路徑:從磁盤根目錄開始一直到檔案名
2.相對路徑:用一個檔案夾下的檔案,相對于目前這個程式所在的檔案而言.如果在同一個檔案中,則相對路勁就是這個檔案名.如果再上一層檔案夾則要使用../

如果相對還是不能了解,來看下這列子:
你朋友要來找你,知道你在那個樓那一層但是不知道那個一個屋,現在你朋友來到這個樓裡相對他知道的這一層然後開始找你在那個房間
這種操作就是相對路勁,例子中是通過這個樓中的這一層開始尋找,也就是相對于這個樓的某一層
我們更推薦大家使用相對路勁,因為我把這個程式的整個檔案發給你的時候,就可以運作,如果使用絕對路徑還需要額外的拷貝外部檔案給你
讀取檔案的方法
read()将檔案中的内容全部讀取出來;弊端 如果檔案很大就會非常的占用記憶體,容易導緻記憶體奔潰
f = open('path1/小娃娃.txt',mode='r',encoding='utf-8')
msg = f.read()
f.close()
print(msg)
結果:
高圓圓
劉亦菲
張柏芝
楊紫
王菲
read()讀取的時候指定讀取到什麼位置,我們指定先讀取前三個内容,然後在使用read()進行讀取會繼續向後讀取,而不會從頭開始讀取
f = open('path1/小娃娃.txt',mode='r',encoding='utf-8')
msg = f.read(3)
msg1 = f.read()
f.close()
print(msg)
print(msg1)
結果:
高圓圓
劉亦菲
張柏芝
楊紫
王菲
上邊現在使用的是r模式這樣讀取的就是文字,如果使用rb模式讀取出來的就是位元組
f = open('path1/小娃娃.txt',mode='rb')
msg = f.read(3)
msg1 = f.read()
f.close()
print(msg)
print(msg1)
結果:
b'\xe9\xab\x98'
b'\xe5\x9c\x86\xe5\x9c\x86\r\n\xe5\x88\x98\xe4\xba\xa6\xe8\x8f\xb2\r\n\xe5\xbc\xa0\xe6\x9f\x8f\xe8\x8a\x9d\r\n\xe6\x9d\xa8\xe7\xb4\xab\r\n\xe7\x8e\x8b\xe8\x8f\xb2'
read()可以放我們讀取多少内容,如果是r模式 read(3)就擷取三個字,如果是rb模式 read(3)就擷取三個位元組
readline()讀取每次隻讀取一行,注意點:readline()讀取出來的資料在後面都有一個\n
f = open('path1/小娃娃.txt',mode='r',encoding='utf-8')
msg1 = f.readline()
msg2 = f.readline()
msg3 = f.readline()
msg4 = f.readline()
f.close()
print(msg1)
print(msg2)
print(msg3)
print(msg4)
結果:
高圓圓
劉亦菲
張柏芝
楊紫
Process finished with exit code 0
解決這個問題隻需要在我們讀取出來的檔案後邊加一個strip()就OK了
f = open('path1/小娃娃.txt',mode='r',encoding='utf-8')
msg1 = f.readline().strip()
msg2 = f.readline().strip()
msg3 = f.readline().strip()
msg4 = f.readline().strip()
f.close()
print(msg1)
print(msg2)
print(msg3)
print(msg4)
結果:
高圓圓
劉亦菲
張柏芝
楊紫
readlines()讀取的是每一行,存放到一個清單當中.
f = open('小娃娃',mode='r',encoding='utf-8')
msg1 = f.readlines()
f.close()
print(msg1)
結果:
['高圓圓\n', '劉亦菲\n', '張柏芝\n', '楊紫']
如果有個較大的檔案我們進行讀取不推薦使用以下方法:
f = open('../path1/弟子規',mode='r',encoding='utf-8')
print(f.read()) #這樣就是将檔案一次性全部讀取到記憶體中,記憶體容易奔潰
推薦使用的是這種方法:
f = open('../path1/弟子規',mode='r',encoding='utf-8')
for line in f:
print(line) #這種方式就是在一行一行的進行讀取,它就執行了下邊的功能
print(f.readline())
print(f.readline())
print(f.readline())
print(f.readline())
注意點:讀完的檔案句柄一定要關閉
寫模式(w,wb)
在寫檔案的時候我們要養成一個寫完檔案就重新整理的習慣. 重新整理flush()
f = open('../path1/小娃娃.txt',mode='w',encoding='utf-8')
f.write('太白很白')
f.flush()
f.close()
結果:
當我選擇使用w模式的時候,在打開檔案的時候就就會把檔案中的所有内容都清空,然後在操作
注意點:如果檔案不存在使用w模式會建立檔案,檔案存在w模式是覆寫寫,在打開檔案時會把檔案中所有的内容清空.
f1 = open('../path1/小娃娃.txt',mode='r',encoding='utf-8')
msg = f1.read()
print(msg)
# 這個是先檢視小娃娃檔案中有哪些内容
f = open('../path1/小娃娃.txt',mode='w',encoding='utf-8')
f.write('太白很白')
f.flush()
f.close()
# 這個是對小娃娃檔案進行覆寫寫操作
f1 = open('../path1/小娃娃.txt',mode='r',encoding='utf-8')
msg = f1.read()
print(msg)
# 檢視覆寫寫後的内容
嘗試讀一讀
f1 = open('../path1/小娃娃.txt',mode='w',encoding='utf-8')
msg = f1.read()
print(msg)
結果:
Traceback (most recent call last):
File "D:/python_object/path2/test.py", line 563, in <module>
msg = f1.read()
io.UnsupportedOperation: not readable #模式是w,不可以執行讀操作
wb模式下,不可以指定打開檔案的編輯,但是寫檔案的時候必須将字元串轉換成utf-8的bytes資料
f = open('../path1/小娃娃.txt',mode='wb')
msg = '你好'.encode('utf-8')
f.write(msg)
f.flush() # 重新整理
f.close()
追加(a,ab)
隻要是a或者ab,a+都是在檔案的末尾寫入,不論光标在任何位置.
在追加模式下,我們寫入的内容後追加在檔案的末尾
f1 = open('../path1/小娃娃.txt',mode='a',encoding='utf-8')
msg = f1.write('這支煙滅了以後')
上圖是沒有追加的圖檔
上圖是追加後的圖檔
ab這個模式,自己試一下就好了
讀寫模式(r+,r+b)
對于讀寫模式,必須是先讀後寫,因為光标預設在開頭位置,當讀完了以後再進行寫入.我們以後使用頻率最高的模式就是r+
看下正确的操作:
f1 = open('../path1/小娃娃.txt',mode='r+',encoding='utf-8')
msg = f1.read()
f1.write('這支煙滅了以後')
f1.flush()
f1.close()
print(msg)
結果:
正常的讀取之後,寫在結尾
看下錯誤的操作:
f1 = open('../path1/小娃娃.txt',mode='r+',encoding='utf-8')
f1.write('小鬼')
msg = f1.read()
f1.flush()
f1.close()
print(msg)
結果:
這樣寫會把小鬼寫在開頭,并且讀出來的是小鬼之後的内容
r+模式一定要記住是先讀後寫
深坑請注意: 在r+模式下. 如果讀取了内容. 不論讀取内容多少. 光标顯示的是多少. 再寫入
或者操作檔案的時候都是在結尾進行的操作.
寫讀模式(w+,w+b)
先将所有的内容清空,然後寫入.最後讀取.但是讀取的内容是空的,不常用
f1 = open('../path1/小娃娃.txt',mode='w+',encoding='utf-8')
f1.write('小鬼')
msg = f1.read()
f1.flush()
f1.close()
print(msg)
有人說,先讀在寫不就行了.w+模式下 其實和w模式一樣,把檔案清空了,在寫的内容.是以很少人用
追加讀(a+,a+b)
a+模式下,不論是先讀還是後讀,都是讀不到資料的
f = open('../path1/小娃娃.txt',mode='a+',encoding='utf-8')
f.write('阿刁')
f.flush()
msg = f.read()
f.close()
print(msg)
還有幾個帶b的模式,其實就是對位元組的一些操作,就不多叙述了.
其他相關操作
seek()
seek(n)光标移動到n位置,注意: 移動機關是byte,所有如果是utf-8的中文部分要是3的倍數
通常我們使用seek都是移動到開頭或者結尾
移動到開頭:seek(0) 實際是seek(0,0)
移動到結尾:seek(0,2)
seek的第二個參數表示的是從哪個位置進行偏移,預設是0,表示開頭,1表示目前位置,2表示結尾
seek()裡邊單獨一個數大于0的就是按照位元組在調節光标
f = open("小娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光标移動到開頭
content = f.read() # 讀取内容, 此時光标移動到結尾
print(content)
f.seek(0) # 再次将光标移動到開頭
f.seek(0, 2) # 将光标移動到結尾
content2 = f.read() # 讀取内容. 什麼都沒有
print(content2)
f.seek(0) # 移動到開頭
f.write("張國榮") # 寫入資訊. 此時光标在9 中文3 * 3個 = 9
f.flush()
f.close()
tell()
使用tell()可以幫我們擷取目前光标在什麼位置
f = open("小娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光标移動到開頭
content = f.read() # 讀取内容, 此時光标移動到結尾
print(content)
f.seek(0) # 再次将光标移動到開頭
f.seek(0, 2) # 将光标移動到結尾
content2 = f.read() # 讀取内容. 什麼都沒有
print(content2)
f.seek(0) # 移動到開頭
f.write("張國榮") # 寫入資訊. 此時光标在9 中⽂文3 * 3個 = 9
print(f.tell()) # 光标位置9
f.flush()
f.close()
truncate() 截斷檔案
f = open("小娃娃", mode="w", encoding="utf-8")
f.write("哈哈") # 寫入兩個字元
f.seek(3) # 光标移動到3, 也就是兩個字中間
f.truncate() # 删掉光标後面的所有内容
f.close()
f = open("小娃娃", mode="r+", encoding="utf-8")
content = f.read(3) # 讀取9個字元
f.seek(4)
print(f.tell())
f.truncate() # 後面的所有内容全部都删掉
# print(content)
f.flush()
f.close()
是以如果想做截斷操作. 記住了. 要先挪動光标. 挪動到你想要截斷的位置. 然後再進行截斷
關于truncate(n), 如果給出了n. 則從開頭進行截斷, 如果不給n, 則從目前位置截斷. 後⾯面
的内容将會被删除
修改檔案以及另一種打開檔案的方
檔案修改: 隻能将檔案中的内容讀取到記憶體中, 将資訊修改完畢, 然後将源檔案删除, 将新檔案的名字改成老檔案的名字.
import os
with open("../path1/小娃娃", mode="r", encoding="utf-8") as f1,\
open("../path1/小娃娃_new", mode="w", encoding="UTF-8") as f2:
content = f1.read()
new_content = content.replace("冰糖葫蘆", "⼤白梨")
f2.write(new_content)
os.remove("../path1/小娃娃") # 删除源檔案
os.rename("../path1/小娃娃_new", "小娃娃") # 重命名新檔案
弊端: ⼀次将所有内容進行讀取. 記憶體溢出. 解決方案: 一行一行的讀取和操作
import os
with open("小娃娃", mode="r", encoding="utf-8") as f1,\
open("小娃娃_new", mode="w", encoding="UTF-8") as f2:
for line in f1:
new_line = line.replace("大白梨", "冰糖葫蘆")
f2.write(new_line)
os.remove("小娃娃") # 删除源⽂檔案
os.rename("小娃娃_new", "小娃娃") # 重命名新檔案
轉載于:https://www.cnblogs.com/guobaoyuan/p/9765496.html