什麼是文件緩存
操做系統提供的虛擬概念,存儲信息(用二進制存儲)編碼
什麼是文件處理操作系統
修改存儲的信息指針
文件的絕對路徑和相對路徑code
D:\Program Files\python\test.py
test.py
項目中儘可能用相對路徑。視頻
操做文件的流程對象
打開文件圖片
f = open('test.py','r',encoding='utf-8') # 以‘r’模式,‘utf-8’格式,打開當前文件夾下的‘test.py’
讀取 或 修改文件ip
data = f.read() # 讀取文件內的內容給到對象 data
保存文件
f.flush() # 快速保存,能夠不使用
關閉文件
f.close() # 告訴操做系統關閉文件
讀取: rt
:讀文本內容,只讀
f = open('test.py','r',encoding='utf-8') data = f.read() # 讀取全部文本內容 print(f.readable()) # 判斷是否可讀 print(f.writable()) # 判斷是否可寫
運行結果:
True False Process finished with exit code 0
瞭解
print(f.readline()) # 一行一行讀取 print(f.readlines()) # 讀取全部行放入列表
循環讀出文本內容
for i in f.read(): # 循環出一個個字符 print(i)
for i in f: # 循環出一行行的內容 --->這種方式更節省內存 print(i)
只寫: wt
:打開文件後先清空文本內容,再寫入新的內容
f = open('test.py','w',encoding='utf-8') print(f.readable()) # 判斷是否可讀 print(f.writable()) # 判斷是否可寫
運行結果:
False True Process finished with exit code 0
瞭解
f.writelines(['abc', 'def', 'ghi']) # 自動拼接列表元素,一行寫入
文件內保存爲:
abcdefghi
只寫: at
:只寫,在文件原內容最後面寫入新的內容
f = open(r'D:\上海python12期視頻\python12期視頻\day 09\test.py', 'at', encoding='utf8') print(f.readable()) print(f.writable())
運行結果:
False True Process finished with exit code 0
使用 w
和 a
模式能夠自動建立一個新的文件,使用 r
模式時,文件必須是已經存在的。
文件的兩種打開方式
兩種方式都不單獨使用,通常與r/w/a聯用
文本方式: t
:打開文本,須要指定字符編碼
指定打開的文本文件的模式爲 rt 或 wt 或 at
,通常能夠省略 t 直接寫做 r 或 w 或 a
。
二進制方式: b
:通常用於音頻/視頻/圖片的保存
指定打開的文本文件的模式爲 rb 或 wb 或 ab
。
因爲每次保存文件後,都須要手動將文件關閉掉,解除對操做系統的佔用,比較麻煩,因此python中提供了一種能夠自動關閉文件的方法。
語法:
with open('test.py', 'r', encoding='utf8') as f: # print(f.read()) # 在這個縮進下不會關閉文件,在這個縮進下對文件操做 data = f.read() # data放到python的內存中 print(data) # 關閉文件(操做系統),但沒有關閉python內存中的文件 print(f.read()) # 因爲不在縮進內,操做系統的文件已經關閉,報錯
1.三種新的文件打開模式(使文件便可讀又可寫),儘可能不要使用。
當一個文件便可讀又可寫的時候,因爲讀取和寫入的時間差,可能出現寫入和讀取的錯誤,沒法正確的讀取到或者寫入咱們想要的信息。
可寫可讀: r+
with open('test.py', 'r+', encoding='utf8') as fr: print(fr.readable()) print(fr.writable()) fr.write('寫入內容') # 光標在文件頭部,會覆蓋後面的字符
運行結果:
True True Process finished with exit code 0
可寫可讀: w+
: w+
和 w
沒有任何區別
with open('test.py', 'w+', encoding='utf8') as fw: print(fw.readable()) print(fw.writable())
運行結果:
True True Process finished with exit code 0
可寫可讀: a+
:a模式默認光標在尾部
with open('test.py','a+',encoding='utf8') as fa: print(fa.readable()) print(fa.writable()) fa.seek(0,0) # 因爲 a 模式打開文件,默認光標在尾部,因此想要讀取文件內容必須將光標移動到文件頭 print(fa.read())
運行結果:
True True Process finished with exit code 0
綜上,若是某些場景真的須要文件可讀又可寫,應該用兩種不一樣的模式打開兩次文件
2.光標的高級應用(移動文件內的光標)
字節:8個二進制位爲一個字節(如下方法都是以字節爲單位)
seek()
:移動光標
with open('test.py', 'rb') as fr: fr.seek(3) # 打開文件後,將光標日後移動3個字節(一箇中文),默認從開頭開始讀取 # 若是 seek 移動的字符不夠 3 個字節,或恰好將漢字的三個字節切分,則會致使亂碼 # whence 參數:規定只有0,1,2 三種模式 fr.seek(3, 0) # 0 表示從開頭日後移動 3 個字符,默認爲 0 ,能夠不寫 fr.seek(3, 1) # 1 表示從中間日後移動 3 個字符 fr.seek(3, 2) # 2 表示從開頭日後移動 3 個字符 print(fr.read()) print(fr.read().decode('utf8'))
tell()
:告訴當前光標所在的位置
with open('test.py', 'rb') as fr: fr.seek(3, 0) print(fr.tell()) # 從文件開頭到當前指針所在位置
運行結果:
3 Process finished with exit code 0
truncate()
:截斷
with open('test.py', 'ab') as fa: fa.truncate(2) #截斷2個字節後的全部字符,若是3個字節一個字符,只能截斷2/3個字符,還會遺留1/3個字符,會形成亂碼
字符:3個字節對應一個字符(中文)
read()
:以字符爲單位,移動光標
with open('test.py', 'r', encoding='utf8') as fr: print(fr.read(3)) # 3 表示 3 個字符,不加默認讀取全部 # 中文和英文都屬於一個字符
文件沒有修改的說法,只有覆蓋。
緩存文件的原理:
import os # 同時打開多個文件 with open('test.py', 'r', encoding='utf-8') as fr, \ open('test_swap.py', 'w', encoding='utf-8') as fw: data = fr.read() data = data.replace('原內容', '修改的內容') # 在新文件裏用修改的內容替換掉原來的內容 fw.write(data) os.remove('test.py') # 刪除原文件 os.rename('test_swap.py', 'test.py') # 將新的文件重命名爲舊文件
可是這樣當文件很大的時候,影響效率,下面是改進:
import os # 同時打開多個文件 with open('test.py', 'r', encoding='utf8') as fr, \ open('test_swap.py', 'w', encoding='utf8') as fw: # 逐行修改保存,再大的文件都能修改 for i in fr: s = '新的內容' i = i.replace('原內容', s) fw.write(i) # fw.flush() # 先保存成功再繼續運行 os.remove('test.py') # 刪除原文件 os.rename('test_swap.py', 'test.py') # 將新的文件重命名爲舊文件
註冊功能:
實現代碼:
# 註冊 count = 0 while count < 3: username_inp = input('請輸入你的用戶名:') pwd_inp = input('請輸入你的密碼:') re_pwd_inp = input('請在此輸入你的密碼:') if not pwd_inp == re_pwd_inp: print('兩次密碼輸入不一致') count += 1 continue with open('user_info.txt', 'a', encoding='utf8') as fa: fa.write(f'{username_inp}:{pwd_inp}\n') # :表示用戶名和密碼的分割;|用戶和用戶之間的分割 fa.flush() break
登陸功能:
實現代碼:
# 登陸 username_inp = input('請輸入你的用戶名:') pwd_inp = input('請輸入你的密碼:') with open('user_info.txt', 'r', encoding='utf8') as fr: for user_info in fr: username, pwd = user_info.split(':') if username.strip() == username_inp and pwd.strip() == pwd_inp: # strip能夠去掉兩端的換行符 print('登陸成功') break else: print('登陸失敗')