一、x模式(控制文件操作模式,與rwa同級)
1 特點
創建不存在文件,文件存在則報錯
可寫不可讀
2 格式
with open('d.txt',mode='x',encoding='utf-8') as f:
f.write('哈哈哈\n')
#d文件存在則報錯,不存在則創建並寫入哈哈哈
二、b模式(控制文件讀寫內容的模式,與t同級)
1.b模式和t模式的區別
t模式:
- 讀寫都必須是以字符串(uncode)為單位
- 只能針對文本文件
- 必須指定字符編碼,即必須指定encoding參數
- 硬盤的二進制讀入內存-》t模式會直接把內存中的二進制encode解碼
b模式(binary):
- 讀寫都是以bytes為單位
- 可以針對所有文件
- 一定不能指定字符編碼,即一定不能指定encoding參數
- 硬盤中的二進制讀入內存-》b模式下不會做任何操作,直接讀入內存
總結:在操作純文本文件方面t模式幫我們省去了編碼與解碼的環節,b模式則需要手動編碼和解碼,所以t在純文本的操作上更方便。非純文本文件只能用b模式
2 b模式應用
with open("a.txt","rb") as f :
print(f.read().decode("utf-8"))
#在b模式下如果想讀文本文件,必須要以源文件存的方式解碼,如果沒有這一步操作輸出的是一個bytes類型
#同理,在寫文件的時候,就要以文件同樣格式去編碼
with open(r"cvc.txt","wb") as f :
f.write("aaaa".encode("utf-8"))
3 循環讀取文件
方式一:自己控制每次讀取的數據的數據量(while)
with open(r"cvc.txt","rb") as f :
while True:
res = f.read(5)#控制每次只讀5個字節的數據
print(res)
if len(res) == 0:
break
方式二:每次讀一行(for)
with open(r"cvc.txt","rb") as f :
for line in f:
print(line)
三、文件操作的其他方法
1 讀相關操作
1.1readline:一次讀一行
with open(r"cvc.txt","rt",encoding="utf-8") as f :
res = f.readline()
print(res)
1.2readlines:把文件內容存放到列表內,以換行符分隔
with open(r"cvc.txt","rt",encoding="utf-8") as f :
res = f.readlines()
print(res)
>>>['aaaa\n', '12321\n', '123123\n', '123123\n', '12321\n', '213312\n', '123\n', '123']
強調:read和readlines都是將文件所有的內容讀到內存中,如果文件過大,容易內存溢出
2 寫相關操作
2.1writelines:readlines的反操作,把列表中的數據寫到文件中
with open(r"cvc.txt","wt",encoding="utf-8") as f :
f.writelines(["aaa","BBB"])#不能寫數字
補充1:b模式下,如果是純英文和數字可以在前面加b前綴得到bytes類型
l = [
b'1111aaa1\n',
b'222bb2',
b'33eee33'
]
l = [
'1111aaa1\n'.encode('utf-8'),
'222bb2'.encode('utf-8'),
'33eee33'.encode('utf-8')
]
#這兩者效果相同
補充2:'上'.encode('utf-8') 等同於bytes('上',encoding='utf-8')
3 flsh刷新
with open('h.txt', mode='wt',encoding='utf-8') as f:
f.write('哈')
f.flush()
#操作系統在把應用程序的數據寫入文件時不是瞬時的,需要攢到一定量再執行,flush可以忽略這個設定直接執行。
4 了解
with open('h.txt', mode='wt',encoding='utf-8') as f:
print(f.readable())#判斷文件是否可讀
print(f.writable())#判斷文件是否可寫
print(f.encoding)#讀取文件存放的字符編碼
print(f.name)#讀取文件名稱
print(f.closed)#判斷文件是否關閉
>>>False
>>>True
>>>utf-8
>>>h.txt
>>>True
四、文件高級操作:控制文件指針的移動
前提:文件指針移動的單位是bytes
只有一種情況下特殊,t模式我們讀取文件時,獲得的是字符串,所以這個時候指針移動的單位是字符
with open('aaa.txt',mode='rt',encoding='utf-8') as f:
res=f.read(4)
print(res)
f.seek(n,模式)n代表的是移動的字節數
1 模式0:參照物是文件開頭
with open(r"cvc.txt","rb") as f :
f.seek(5,0)#從開頭把光標移動到底5個字節處
f.seek(111,0)#從開頭把光標移動到第111字節處,如果沒有這么多,就移到最后一個
2 模式1:參照物是光標當前所在位置
with open(r"cvc.txt","rb") as f :
f.seek(3,1)#在第三個字節處
f.seek(1,1)#在第四個字節處
3 模式2:參照物是文件末尾,應該是倒着移動的n為負數
with open(r"cvc.txt","rb") as f :
f.seek(-1,2)#在文件倒數第一個字節處
f.seek(-2,2)#在文件倒數第二個字節處
強調 0模式可以在t模式下使用,1,2模式只能在b模式下使用
4 tell獲取文件當前光標所在位置
with open(r"cvc.txt","rb") as f :
f.seek(-1,2)
f.seek(-2,2)
res = f.tell()
print(res)
>>>3
五、文件修改
強調
- 硬盤空間是無法修改的,硬盤中的數據的更新都是用新的值取覆蓋舊的值
- 內存中的數據是可以修改的
# 文件a.txt內容如下
張一蛋 山東 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
# 執行操作
with open('a.txt',mode='r+t',encoding='utf-8') as f:
f.seek(9)
f.write('<婦女主任>')
# 文件修改后的內容如下
張一蛋<婦女主任> 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
因此如果需要修改文件,只能把文件的數據從硬盤讀到內存中,然后在內存中修改最后覆蓋源文件
方式一
#實現思路:講文件的內容一次性全部讀入內存中,然后再內存中修改,最后覆蓋原文件
#優點:在文件修改的過程中只有一個文件
#缺點:一次性讀入內存會過多占用內存空間
with open("b.txt","r",encoding="utf-8") as f :
info = f.read()
with open("b.txt","w",encoding="utf-8") as f1:
f1.write(info.replace("a","b"))
方式二
#實現思路:打開原文件的同時,創建一個臨時文件,把原文件的數據一行一行的讀入內存,再保存到臨時文件,最后把原文件刪除,重命名臨時文件
#優點:不會占用很多內存空間,同時出現在內存中的數據只有一行
#缺點:文件修改的過程中會出現兩個文件
import os
with open("b.txt","r",encoding="utf-8") as f1,\
open(".b.txt.swap","w",encoding="utf-8") as f2:
for line in f1:
f2.write(line.replace("b","a"))
os.remove("b.txt")
os.rename(".b.txt.swap","b.txt")