(八)檔案操作
一、相對路徑和絕對路徑
1. 絕對路徑:從磁碟根⽬錄開始⼀直到⽂件名.
2. 相對路徑:同⼀個⽂件夾下的⽂件. 相對於當前這個程式所在的⽂件夾⽽⾔. 如果在同⼀個⽂件夾中. 則相對路徑就是這個⽂件名. 如果在上⼀層⽂件夾. 則要使用“../”退回到上一個資料夾,再去查詢相應的資料夾和檔案。
如下是相對路徑:
絕對路徑如下:
二、 初識⽂件操作
使⽤python來讀寫⽂件是非常簡單的操作. 我們使⽤open()函式來開啟⼀個⽂件, 獲取到⽂件控制代碼. 然後通過⽂件控制代碼就可以進⾏各種各樣的操作了. 根據開啟⽅式的不同能夠執⾏的操作也會有相應的差異.
開啟⽂件的⽅式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b 預設使⽤的是r(只讀)模式
- read() 將⽂件中的內容全部讀取出來. 弊端: 佔記憶體. 如果⽂件過⼤.容易導致記憶體崩潰。
f = open("test.txt", mode="r", encoding="utf-8")#在此py檔案下,新建一個test.txt的檔案 content = f.read() print(content)
2. read(n) 讀取n個字元. 需要注意的是. 如果再次讀取. 那麼會在當前位置繼續去讀⽽不
是從頭讀, 如果使⽤的是rb模式. 則讀取出來的是n個位元組。
f = open("test.txt", mode="r" encoding="utf-8") content = f.read(3) print(content)
3. readline() ⼀次讀取⼀⾏資料, 注意: readline()結尾, 注意每次讀取出來的資料都會有⼀
個\n 所以呢. 需要我們使⽤strip()⽅法來去掉\n或者空格
f = open("../def/哇擦.txt", mode="r", encoding="utf-8") content = f.readline() print(content)
4. readlines()將每⼀⾏形成⼀個元素, 放到⼀個列表中. 將所有的內容都讀取出來. 所以
也是容易出現記憶體崩潰的問題.不推薦使⽤
f = open("test.txt", mode="r", encoding="utf-8") lst = f.readlines() print(lst) for line in lst: print(line.strip())
5. 迴圈讀取. 這種⽅式是組好的. 每次讀取⼀⾏內容.不會產⽣記憶體溢位的問題.
f = open("test.txt", mode="r", encoding="utf-8")
for line in f:
print(line.strip())
6.注意: 讀取完的⽂件控制代碼⼀定要關閉 f.close()
三. 寫模式(w, wb)
寫的時候注意. 如果沒有⽂件. 則會建立⽂件, 如果⽂件存在. 則將原件中原來的內容刪除, 再寫入新內容
f = open("test.txt", mode="w", encoding="utf-8")
f.write("⾦⽑獅王")
f.flush() # 重新整理. 養成好習慣
f.close()
wb模式下. 可以不指定開啟⽂件的編碼. 但是在寫⽂件的時候必須將字串轉化成utf-8的bytes資料
f = open("test.txt", mode="wb")
f.write("⾦⽑獅王".encode("utf-8"))
f.flush()
f.close()
四. 追加(a, ab)
在追加模式下. 我們寫入的內容會追加在⽂件的結尾。有這個檔案,則會在末尾追加。如果沒有此檔案,則會建立。
f = open("test.txt", mode="a", encoding="utf-8") f.write("張三的最愛") f.flush() f.close()
ab模式程式碼如下:
f = open("test.txt", mode="ab") f.write("麻花藤的最愛".encode('utf-8')) f.flush() f.close()
五. 讀寫模式(r+, r+b)
對於讀寫模式. 必須是先讀. 因為預設游標是在開頭的. 準備讀取的. 當讀完了之後再進⾏寫入. 我們以後使⽤頻率最⾼的模式就是r+
f = open("test.txt", mode="r+", encoding="utf-8") content = f.read() f.write("麻花藤的最愛") print(content) f.flush() f.close()
注意:r+模式下. 必須是先讀取. 然後再寫入
六. 寫讀(w+, w+b)
先將所有的內容清空. 然後寫入. 最後讀取. 但是讀取的內容是空的, 不常⽤。 w+ 模式下, ⼀開始讀取不到資料. 然後寫的時候再將原來的內容清空. 所以, 很少⽤。
f = open("test.txt", mode="w+", encoding="utf-8") f.write("哈哈") content = f.read() print(content) f.flush() f.close()
七. 追加讀(a+)
a+模式下, 不論先讀還是後讀. 都是讀取不到資料的.
f = open("⼩娃娃", mode="a+", encoding="utf-8") f.write("⻢化騰") content = f.read() print(content) f.flush() f.close()
還有⼀些其他的帶b的操作. 就不多贅述了. 就是把字元換成位元組. 僅此⽽已
八. 其他相關操作
1. seek(n) 游標移動到n位置, 注意, 移動的單位是byte. 所以如果是UTF-8的中⽂部分要
是3的倍數.
通常我們使⽤seek都是移動到開頭或者結尾.
移動到開頭: seek(0)
移動到結尾: seek(0,2) seek的第⼆個引數表⽰的是從哪個位置進⾏偏移, 預設是0, 表
⽰開頭, 1表⽰當前位置, 2表⽰結尾
使用時,不知道有沒有遇到這個錯誤:io.UnsupportedOperation: can't do nonzero cur-relative seeks
這個問題主要是因為在python3和python2的問題,如果在Python2中是不會報錯的,Python3則會報錯。因為Pyhon3在文字檔案中,沒有使用b模式選項開啟的檔案,只允許從檔案頭開始計算相對位置,從檔案尾計算時就會引發異常。
f = open("test.txt", mode="rb") f.seek(0) # 游標移動到開頭 content = f.read() # 讀取內容, 此時游標移動到結尾 print(content) print(f.tell()) f.seek(-3, 1) # 再次將游標移動到開頭 content = f.read(6) # 讀取內容, 此時游標移動到結尾 print(content) print(f.tell()) f.flush() f.close()
2.tell()方法也使用了,就是告訴使用者,當前游標在什麼位置。計算時,是按照,位元組數累加的。
3.truncate()
此方法的作用就是,刪除游標後面的所有內容。
f = open('test.txt',mode='w',encoding='utf-8')#此行程式碼執行後,檔案中就沒有文字了,所以需要下面的f.write('哈呵護'),寫入一些值。這是因為‘w’模式就是這個特點。 f.write('哈呵護') c = f.seek(6) print(c) f.truncate() f = open('test.txt', mode='r+', encoding='utf-8') print(f.read()) f.seek(0) f.seek(3) f.truncate() print(f.read())
九. 修改⽂件以及另⼀種開啟⽂件的⽅式
⽂件修改: 只能將⽂件中的內容讀取到記憶體中, 將資訊修改完畢, 然後將源⽂件刪除, 將新⽂件的名字改成老⽂件的名字.
# ⽂件修改
import os with open("test.txt", mode="r", encoding="utf-8") as f1,\ open("test_new.txt", mode="w", encoding="UTF-8") as f2: content = f1.read() new_content = content.replace("冰糖葫蘆", "⼤⽩梨") f2.write(new_content) os.remove("⼩娃娃") # 刪除源⽂件 os.rename("test_new.txt", "⼩娃娃") # 重新命名新⽂件 弊端: ⼀次將所有內容進⾏讀取. 記憶體溢位. 解決⽅案: ⼀⾏⼀⾏的讀取和操作 import os with open("test.txt", 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("test.txt") # 刪除源⽂件 os.rename("test_new.txt", "test.txt") # 重新命名新⽂件