1、 可讀可寫:
# r+t :可讀可寫 一打開光標就在開始位置
直接寫將致使原始數據被覆蓋
# w+t:可讀可寫 一打開光標就在開始位置
會把原始全都清空了
要使用可讀可寫模式 首先要保證 你知道數據是如何編碼的
# a+t : 可讀可寫 一打開光標就在文件末尾python
with open('a.txt',mode='r+t',encoding='utf-8') as f: print(f.readable()) #判斷是否可讀 print(f.writable()) #判斷是否可寫 msg=f.readline() #只讀一行 print(msg) f.write('xxxxxxxxxxx\n') ---------------------------------------------------- True True
a.txtide
xxxxxxxxxxx \n (回車)
2、控制文件內的指針移動編碼
# 文件內指針移動,只有t模式下的read(n),n表明的字符的個數
# 除此之外文件內指針的移動都是以字節爲單位spa
with open('a.txt',mode='rt',encoding='utf-8') as f: msg=f.read(1) #()不寫所有讀 print(msg) ------------------------------- x
# 使用b模式打開後轉成文本模式的使用decode解碼(指定編碼格式) with open('a.txt',mode='rb') as f: msg=f.read(3) print(msg.decode('utf-8')) ------------------------------------------- xxx
a.txt指針
xxxxxxxxxxx (\n 回車)
# f.seek(offset,whence)有兩個參數:
# offset: 表明控制指針移動的字節數
# whence: 表明參照什麼位置進行移動
# whence = 0: 參照文件開頭(默認的),特殊???,能夠在t和b模式下使用
# whence = 1: 參照當前所在的位置,必須在b模式下用
# whence = 2: 參照文件末尾,必須在b模式下用code
a.txt
內存
123456789
py
utf-8
with open('a.txt',mode='rt',encoding='utf-8') as f: f.seek(6,0) #從文件開頭,print 時會讀到下一個 msg=f.read(1) print(msg) ------------------------------------------------------------- 7 with open('a.txt',mode='rb') as f: f.seek(3,0) msg=f.read(3) print(msg.decode('utf-8')) ------------------------------------------- 456 with open('a.txt',mode='rb') as f: # utf-8中 b:模式是讀:「字節」(3個字節是一個字符) t:模式是字符(一個漢字) msg=f.read(3) print(msg.decode('utf-8')) print(f.tell()) # f.seek(6,0) f.seek(3,1) msg1=f.read(3) print(msg1.decode('utf-8')) --------------------------------------------------- 123 3 789 # 接上面 例子: with open("a.txt",'rb')as f: f.seek(8,0) print(f.read(1).decode('utf-8')) # utf-8中 f.read("字節") b:模式是讀:「字節」(3個字節是一個字符) t:模式是字符(一個漢字) # 取字符e # 取到第2個t # 若是一行都是(utf-8)中文,(b模式)都是按照3個字節是一個字符來算,如有中文也有英文,f.read(1) 應該按照一個字節取,中文仍是算3個,若全是中文應該是f.read(3) # 由於3個字節一箇中文
a.txtci
××× 123456789 jkljkljhkljhkl
1.py
rem
with open('a.txt',mode='rb') as f: msg=f.read(3) print(msg.decode('utf-8')) print(f.tell()) #統計文件的字符數,utf-8中 一箇中文字符佔3個字節數 # f.seek(6,0) # #0模式,是0模式日後移動的位置再在當前光標處繼續移動 字節(b模式的話)。 f.seek(3,1) #若是最開始用1模式的話,是與0模式效果同樣,由於都是從光標開頭出開始 msg1=f.read(3) print(msg1.decode('utf-8')) ---------------------------------------------- 中 3 人
py
with open('a.txt',mode='rb') as f: # f.seek(0,2) # print(f.tell()) f.seek(-3,2) # 2模式前面必須是負數,由於正數的話是日後取值(2模式原本就是文件末尾) msg=f.read(3) print(msg.decode('utf-8')) -------------------------------------- hkl
with open('access.log',mode='rb') as f: f.seek(0,2) # 當前位置是147bytes while True: line=f.readline() # 當前位置是196bytes # print(f.tell()) if len(line) == 0: # 沒有新的一行內容追加進來 pass else: # 有新的一行內容追加進來 print(line.decode('utf-8'),end='')
with open('access.log',mode='rb') as f: f.seek(0,2) # 當前位置是147bytes while True: line=f.readline() # 當前位置是196bytes if len(line) != 0: print(line.decode('utf-8'),end='')
with open('a.txt',mode='r+t',encoding='utf-8') as f: f.truncate(6)
a.txt (舊)
×××
a.txt (新)
中華
import time with open('access.log','at',encoding='utf-8') as f: f.write('%s alex給egon轉帳了1個億\n' %time.strftime('%Y-%m-%d %H:%M:%S'))
3、文件修改的兩種方式
# 修改文件的方式一:
# 1 將文件內容由硬盤所有讀入內存
# 2 在內存中完成修改
# 3 將內存中修改後的結果覆蓋寫回硬盤
a.txt
alex
py (將文件a.txt中的alex修改爲爲"dsb")
with open('a.txt',mode='rt',encoding='utf-8') as f: all_data=f.read() print(all_data,type(all_data)) with open('a.txt',mode='wt',encoding='utf-8') as f: f.write(all_data.replace('alex','dsb'))
# 修改文件的方式二: (將文件a.txt中的"alex"修改爲爲"dsb")
# 1 以讀的方式打開源文件,以寫的方式打開一個臨時文件
# 2 從源文件中每讀同樣內容修改完畢後寫入臨時文件,直到源文件讀取完畢
# 3 刪掉源文件,將臨時文件重命名爲源文件名
import os with open('a.txt',mode='rt',encoding='utf-8') as read_f,open('.a.txt.swap',mode='wt',encoding='utf-8') as write_f: for line in read_f: write_f.write(line.replace('alex','dsb')) os.remove('a.txt') os.rename('.a.txt.swap','a.txt')
# 方式一:
# 優勢: 在文件修改的過程當中硬盤上始終一份數據
# 缺點: 佔用內存過多,不適用於大文件
# 方式二:
# 優勢: 同一時刻在內存中只存在源文件的一行內容,不會過多地佔用內存
# 缺點: 在文件修改的過程當中會出現源文件與臨時文件共存,硬盤上同一時刻會有兩份數據,即在修改的過程當中會過多的佔用硬盤,
# 把列表寫入到文件中
# 將列表轉成字符,而後再寫入到文件中
l=[1,2,3,'a','b','c','d'] with open ("c.txt",'w+t',encoding='utf-8') as f: f.write(str(l))
c.txt
[1, 2, 3, 'a', 'b', 'c', 'd']