文件操作
創(chuàng)新互聯(lián)公司一直通過網(wǎng)站建設(shè)和網(wǎng)站營銷幫助企業(yè)獲得更多客戶資源。 以"深度挖掘,量身打造,注重實效"的一站式服務(wù),以成都網(wǎng)站設(shè)計、網(wǎng)站制作、移動互聯(lián)產(chǎn)品、成都營銷網(wǎng)站建設(shè)服務(wù)為核心業(yè)務(wù)。十余年網(wǎng)站制作的經(jīng)驗,使用新網(wǎng)站建設(shè)技術(shù),全新開發(fā)出的標準網(wǎng)站,不但價格便宜而且實用、靈活,特別適合中小公司網(wǎng)站制作。網(wǎng)站管理系統(tǒng)簡單易用,維護方便,您可以完全操作網(wǎng)站資料,是中小公司快速網(wǎng)站建設(shè)的選擇。初識文件操作
使用python來讀寫文件是非常簡單的操作,我們使用open()函數(shù)來打開某個文件,獲取到文件句柄,然后通過文件句柄就可以進行各種各樣的操作了。根據(jù)打開形式的不同能夠執(zhí)行的操作也會有相應(yīng)的差異。操作文件的方式一般有如下:
r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b
默認使用的是r(只讀)模式
只讀操作(r, rb)
f = open("python", mode="r", encoding="utf-8")
content = f.read()
print(content)
f.close()
python.txt
這是python文件
運行結(jié)果:
這是python文件
Process finished with exit code 0
需要注意encoding表示編碼集,根據(jù)文件的實際保存編碼進行獲取數(shù)據(jù),對于我們來說,使用更多的是utf-8。
rb. 讀取出來的數(shù)據(jù)是bytes類型,,在rb模式下,不能選擇encoding字符集。
f = open("python", mode="rb")
content = f.read()
print(content)
f.close()
python.txt
這是python文件
運行結(jié)果:
b'\xe8\xbf\x99\xe6\x98\xafpython\xe6\x96\x87\xe4\xbb\xb6'
Process finished with exit code 0
rb的作用: 在讀取非文本文件的時候. 比如讀取MP3、圖像、視頻等信息的時候就需要用到rb。因為這種數(shù)據(jù)是沒辦法直接顯示出來的. 在后面文件上傳下載的時候還會用到。還有,我們看的直播,實際上都是這種數(shù)據(jù)。
路徑
一般分為絕對路徑和相對路徑:
1. 絕對路徑:從磁盤根目錄開始一直到文件名。
2. 相對路徑:同一個文件夾下的文件,相對于當(dāng)前這個程序所在的文件夾而言,如果在同一個文件夾中。則相對路徑就是這個文件名,如果在上一層文件夾,則要使用../表示上一層文件,如果在上多層文件夾中,則需要使用多次../。
一般在開發(fā)過程中推薦大家使用相對路徑。因為在我們把程序拷貝給別人使用的時候. 直接把整個項目文件拷貝出去就能運行,但是如果使用絕對路徑,那還需要拷貝外部的文件。
獲取文件
read()
將文件中的內(nèi)容全部讀取出來。弊端:占內(nèi)存。如果文件過大,容易導(dǎo)致內(nèi)存崩潰,使用時應(yīng)該小心謹慎。
f = open("../FileOne/靜夜思.txt", mode="r", encoding="utf-8")
content = f.read()
print(content)
靜夜思.txt
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
運行結(jié)果:
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
Process finished with exit code 0
read(n)
讀取n個字符,需要注意的是,如果再次讀取,那么會在當(dāng)前位置繼續(xù)去讀而不是從頭讀,如果使用的是rb模式,則讀取出來的是n個字節(jié)。
f = open("../FileOne/靜夜思.txt", mode="r", encoding="utf-8")
content = f.read(4)
contentOne = f.read(5)
print(content)
print(contentOne)
靜夜思.txt
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
運行結(jié)果:
床前明月
光
疑是地
Process finished with exit code 0
值得注意的是,在這里換行符表示一個字節(jié)。前面4個字節(jié),后面接著輸出5個字節(jié)。
f = open("../FileOne/靜夜思.txt", mode="rb")
content = f.read(4)
contentOne = f.read(5)
print(content)
print(contentOne)
靜夜思.txt
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
運行結(jié)果:
b'\xe5\xba\x8a\xe5'
b'\x89\x8d\xe6\x98\x8e'
Process finished with exit code 0
readline()
一次讀取一行數(shù)據(jù),注意:readline()結(jié)尾,注意每次讀取出來的數(shù)據(jù)都會有一個\n 。所以呢,需要我們使用strip()方法來去掉\n或者空格,當(dāng)然,我們也可以在print后面加上end=""去掉空格。
f = open("../FileOne/靜夜思.txt", mode="r", encoding="utf-8")
contentOne = f.readline()
contentTwo = f.readline()
contentThree = f.readline()
contentFour = f.readline()
print(contentOne.strip())
print(contentTwo.strip())
print(contentThree, end="")
print(contentFour, end="")
靜夜思.txt
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
運行結(jié)果:
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
Process finished with exit code 0
readlines()
將每一行形成一個元素,放到一個列表中,將所有的內(nèi)容都讀取出來,所以也是,容易出現(xiàn)內(nèi)存崩潰的問題,一般不推薦不推薦使用。
f = open("../FileOne/靜夜思.txt", mode="r", encoding="utf-8")
lst = f.readlines()
print(lst)
for line in lst:
print(line.strip())
靜夜思.txt
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
['床前明月光\n', '疑是地上霜\n', '舉頭望明月\n', '低頭思故鄉(xiāng)']
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
Process finished with exit code 0
從列表里面我們可以看出,每次獲取的行后面都會有換行符/n。因此,打印過程中我們應(yīng)該使用strip()或者end = ()去掉換行。
循環(huán)讀取
f = open("../FileOne/靜夜思.txt", mode="r", encoding="utf-8")
for line in f:
print(line.strip())
靜夜思.txt
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
運行結(jié)果:
床前明月光
疑是地上霜
舉頭望明月
低頭思故鄉(xiāng)
Process finished with exit code 0
這種方式是事先就組好了,每次讀取一行的內(nèi)容,不會產(chǎn)生內(nèi)存溢出的問題。
注意:
在每次讀取完文件時,應(yīng)該關(guān)閉文件句柄。f.closed()
在執(zhí)行操作過后可使用刷新機制對文件進行刷新。f.flush()
寫模式(r,rw)
寫的時候注意,如果沒有文件,則會創(chuàng)建文件,如果文件存在,則將原件中原來的內(nèi)容刪除,再寫入新內(nèi)容。
f = open("?娃娃", mode="w", encoding="utf-8")
f.write("??獅王")
# f.read() # 嘗試讀取文件,此時只是寫,拋出io.UnsupportedOperation: not readable
f.flush() # 刷新. 養(yǎng)成好習(xí)慣
f.close()
創(chuàng)建了文件:小娃娃
??獅王
運行結(jié)果:
Process finished with exit code 0
本次文件寫操作執(zhí)行完畢后,程序結(jié)束,控制臺沒有輸出值,只是在列表中創(chuàng)建了文件。
f = open("?娃娃", mode="wb")
f.write("??獅王".encode("utf-8"))
f.flush()
f.close()
創(chuàng)建文件:小娃娃
??獅王
運行結(jié)果:
Process finished with exit code 0
wb模式下,可以不指定文件的編碼,但是在寫文件的時候必須將字符串轉(zhuǎn)換為utf-8的bytes數(shù)據(jù),如果不轉(zhuǎn)化,將會出現(xiàn)一下的錯誤。
TypeError: a bytes-like object is required, not 'str'
追加(a,ab)
在追加模式下. 我們寫入的內(nèi)容會追加在文件的結(jié)尾.
f = open("?娃娃", mode="a", encoding="utf-8")
f.write("麻花藤的最愛")
f.write("是小學(xué)生")
f.flush()
f.close()
創(chuàng)建文件:小娃娃
麻花藤的最愛是小學(xué)生
運行結(jié)果:
Process finished with exit code 0
f = open("?娃娃", mode="ab")
f.write("麻花藤的最愛".encode())
f.write("是小學(xué)生".encode())
f.flush()
f.close()
創(chuàng)建文件:小娃娃
麻花藤的最愛是小學(xué)生
運行結(jié)果:
Process finished with exit code 0
由于編譯器默認的是utf-8,所以在小娃娃文件中顯示的是未改變的字符。
讀寫模式(r+,r+b)
對于讀寫模式,必須是先讀。因為默認光標是在開頭的,準備讀取的,當(dāng)讀完了之后再進行寫入,我們以后使用頻率高的模式就是r+。
f = open("?娃娃", mode="r+", encoding="utf-8")
content = f.read()
f.write("麻花藤的最愛")
print(content)
f.flush()
f.close()
運行前的文件:小娃娃
麻花藤的最愛
運行后的文件:小娃娃
麻花藤的最愛麻花藤的最愛
運行結(jié)果:
麻花藤的最愛
Process finished with exit code 0
在正常的讀取后,文件的寫入在結(jié)尾。
下面演示錯誤操作:
f = open("?娃娃", mode="r+", encoding="utf-8")
f.write("哈哈")
content = f.read()
print(content)
f.flush()
f.close()
運行前的文件:小娃娃
麻花藤的最愛
運行后的文件:小娃娃
哈哈藤的最愛
運行結(jié)果:
藤的最愛
Process finished with exit code 0
在沒有任何操作之前,默認的光標在開頭,當(dāng)寫入“哈哈”以后,“麻花”二字被覆蓋,且光標往后移動了兩個位置,默認讀取從光標后開始讀取。
總結(jié),在r+模式下,必須是先讀取,再寫入。
寫讀(w+,w+b)
先將所有的內(nèi)容清空,然后寫入,最后讀取,但是讀取的內(nèi)容是空的,一般不常用。
f = open("?娃娃", mode="w+", encoding="utf-8")
f.write("哈哈")
content = f.read()
print(content)
f.flush()
f.close()
運行前的文件:小娃娃
麻花藤的最愛
運行后的文件:小娃娃
哈哈
運行結(jié)果:
Process finished with exit code 0
那么可能有同學(xué)會問,先讀不就好了么?
錯。理由:w+ 模式下, 一開始讀取不到數(shù)據(jù),然后寫的時候再將原來的內(nèi)容清空,所以這種操作方式很少用。
追加讀(a+)
a+模式下,不論先讀還是后讀,都是讀取不到數(shù)據(jù)的。
f = open("?娃娃", mode="a+", encoding="utf-8")
f.write("麻花藤")
content = f.read()
print(content)
f.flush()
f.close()
運行前的文件:小娃娃
愛笑的眼睛
運行后的文件
愛笑的眼睛麻花藤
運行結(jié)果:
Process finished with exit code 0
還有一些其它帶b的操作,就不多贅述了,就是把字符換成字節(jié),僅此而已。
其它相關(guān)操作
seek(n)
光標移動到n位置,注意,移動的單位是byte,所以如果是utf-8的中文部分要是3的倍數(shù)。
通常我們使用seek都是移動到開頭或者結(jié)尾。
移動到開頭:seek(0) 。鄭州人流價格 http://www.zzzykdfk.com/
移動到結(jié)尾:seek(0,2),seek的第一個參數(shù)表示的是從哪個位置進行偏移,默認是0,表示開頭,1表示當(dāng)前位置,2表示結(jié)尾。
f = open("?娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光標移動到開頭
content = f.read() # 讀取內(nèi)容, 此時光標移動到結(jié)尾
print(content)
f.seek(0) # 再次將光標移動到開頭
f.seek(0, 2) # 將光標移動到結(jié)尾
content2 = f.read() # 讀取內(nèi)容. 什么都沒有
print(content2)
f.seek(0) # 移動到開頭
f.write("張國榮") # 寫?信息. 此時光標在9 中?3 * 3個 = 9
f.flush()
f.close()
運行前的文件:小娃娃
123456789
運行后的文件:小娃娃
張國榮
運行結(jié)果:
123456789
Process finished with exit code 0
tell()
獲取到當(dāng)前光標位置。
f = open("?娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光標移動到開頭
content = f.read() # 讀取內(nèi)容, 此時光標移動到結(jié)尾
print(content)
f.seek(0) # 再次將光標移動到開頭
f.seek(0, 2) # 將光標移動到結(jié)尾
content2 = f.read() # 讀取內(nèi)容. 什么都沒有
print(content2)
f.seek(0) # 移動到開頭
f.write("張國榮") # 寫?信息. 此時光標在9 中?3 * 3個 = 9
print(f.tell()) # 光標位置9
f.flush()
f.close()
運行前的文件:小娃娃
123456789
運行后的文件:小娃娃
123456789
9
Process finished with exit code 0
truncate()
截斷文件光標后的內(nèi)容,日常操作過程中幾乎不用。
f = open("小娃娃", mode="w", encoding="utf-8")
f.write("哈哈") # 寫?兩個字符
f.seek(3) # 光標移動到3, 也就是兩個字中間
f.truncate() # 刪掉光標后?的所有內(nèi)容
f.close()
運行前的文件:小娃娃
麻花藤最愛的人
運行后的文件
哈
運行結(jié)果:
Process finished with exit code 0
深坑請注意:在r+模式下,如果讀取了內(nèi)容,不論讀取內(nèi)容多少,光標顯示的是多少,再寫入或者操作文件的時候都是在結(jié)尾進行的操作。
所以如果想做截斷操作,記住了,要先挪動光標,挪動到你想要截斷的位置,然后再進行截斷關(guān)于truncate(n), 如果給出了n. 則從開頭開頭進行截斷,如果不給n,則從當(dāng)前位置截斷,后面的內(nèi)容將會被刪除。
修改文件以及另一種打開文件的方式
import os
with open("?娃娃", mode="r", encoding="utf-8") as f1, \
open("?娃娃_new", mode="w", encoding="UTF-8") as f2:
content = f1.read()
new_content = content.replace("冰糖葫蘆", "??梨")
f2.write(new_content)
os.remove("?娃娃") # 刪除源?件
os.rename("?娃娃_new", "?娃娃") # 重命名新?件
弊端:一次將所有內(nèi)容進行讀取,導(dǎo)致內(nèi)存溢出,解決?案: 一行一行的讀取和操作。
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", "?娃娃") # 重命名新?件
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。