文章目錄
一.文件路徑
絕對路徑
絕對路徑指的是從盤符開始的,直接到達目標文件位置的目錄下的絕對位置。 絕對路徑完整的描述了文件位置。例如,在 D 盤下的 code 文件夾中有一個 test.py 文件,那麼路徑就是 D:/code/test.py
。
相對路徑
相對路徑就是指由這個文件所在的路徑引起的跟其它文件(或文件夾)的路徑關係。例如,在 D 盤 work 文件下有一個 test.txt 文件,那麼它相對上文的 test.py 文件的路徑就是 /work/test.txt
。
二.文件操作
操作流程
# 1. 打開文件,得到一個文件句柄並賦值給一個變量
f = open('Hape.txt', mode='r', encoding='utf-8') # 默認打開模式爲只讀模式r
# 2. 通過文件句柄對文件進行操作,對於文件的操作有很多種,read只是其中一種
content = f.read() # f.read([size]) 從文件中讀取指定的字節數,若未給定或爲負數則讀取所有
# 3. 關閉文件
f.close()
注意: 打開一個文件包含兩部分資源:操作系統級打開的文件+應用程序的變量。在操作完畢該文件時,必須將這兩部分資源全部回收。回收操作有:
f.close() # 回收操作系統級打開的文件
del f # 回收應用程序級的變量
其中del f
必須放在f.close
後面,否則就會導致操作系統級的文件無法關閉,浪費內存資源。而 Python 的自動的垃圾回收機制讓我們不用再考慮del f
的操作。但是必須要關閉文件f.close
。
爲了避免漏寫f.close
的情況,我們可以藉助with
關鍵字。with
不僅有更優雅的語法,還可以很好地處理上下文環境產生的異常。
with open('Hape.txt', mode='r', encoding='utf-8') as f:
pass
同時處理兩個文件
# 將文件a中的內容寫入文件b中
with open('a.txt', 'r') as fa, open('b.txt', 'w') as fb:
content = fa.read()
fb.write(content)
文件編碼
f = open(…) 是由操作系統打開文件,那麼如果我們沒有爲 open 指定編碼,那麼操作系統就會用自己的默認編碼去打開文件。在 Windows 下是 gbk, Linux 下是 utf-8。 若要保證不亂碼,文件用什麼方式存儲的,就用什麼方式打開。
文件的打開模式
-
打開文件的模式有(默認爲文本模式):
r
,只讀模式【默認模式,文件必須存在,不存在則拋出異常】
w
,只寫模式【不可讀;不存在則創建;存在則清空內容】
a
, 只追加寫模式【不可讀;不存在則創建;存在則只追加內容】 -
對於非文本文件,我們只能使用 b 模式,“b” 表示以字節的方式操作(而所有文件也都是以字節的形式存儲的,使用這種模式無需考慮文本文件的字符編碼、圖片文件的 jgp 格式、視頻文件的 avi 格式)
rb
wb
ab
注:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型,不能指定編碼 -
**‘+’**模式(就是增加了一個功能)
r+
, 讀寫【可讀,可寫, 文件指針會放在文件的開頭】
w+
,寫讀【可寫,可讀, 文件不存在則創建文件,存在則從文件的開頭開始編輯】
a+
, 寫讀【可寫,可讀,文件不存在則創建文件,文件已存在則文件指針放在文件的結尾】 -
以bytes類型操作的讀寫,寫讀,寫讀模式
r+b
, 讀寫【可讀,可寫】
w+b
,寫讀【可寫,可讀】
a+b
, 寫讀【可寫,可讀】
文件操作方法
常用操作
f.read(size)
# 從文件指針處開始讀取指定的 字節/字符 數,如果未給定或爲負則讀取所有。
f.read(3)
# 文件打開爲文本模式時,讀取三個字符
# 文件打開爲bytes模式時,讀取三個字節
f.write()
用於向文件中寫入指定字符串。
在文件關閉前或緩衝區刷新前,字符串內容存儲在緩衝區中,這時你在文件中是看不到寫入的內容的。
如果文件打開模式帶 b,那寫入文件內容時,str (參數)要用 encode 方法轉爲 bytes 形式,否則報錯:TypeError: a bytes-like object is required, not ‘str’。
with open('a.txt', 'r+b') as f:
content = f.read()
f.write("人生苦短".encode('utf-8'))
f.seek(offset, whence)
用於移動文件讀取指針到指定位置。
offset 代表需要移動偏移的字節數,如果是負數表示從倒數第幾位開始。
whence 默認值爲 0。給 offset 定義一個參數,表示要從哪個位置開始偏移;0 代表從文件開頭開始算起,1 代表從當前位置開始算起,2 代表從文件末尾算起。其中 1 和 2 必須在bytes模式下進行。
注意: 無論 whence 選擇什麼值,指針都是以 bytes 爲單位移動的。
f.tell()
返回文件指針當前的位置
f.readline(size)
從文件中讀取整行,包括行末的'\n'
。若指定了一個非負參數,則返回指定大小的 字符/字節 數。
'''文件中的內容:
人生苦短
我用python
富強文明民主和諧美麗
'''
with open('a.txt', 'r+', encoding='utf-8') as f:
line1 = f.readline()
line2 = f.readline(3)
line3 = f.readline(2)
line4 = f.readline()
print(line1, line2, line3, line4, sep='*')
'''輸出結果:
人生苦短
*我用p*yt*hon
'''
f.readlines()
讀取文件的所有行,並返回一個列表。
'''文件中的內容:
人生苦短
我用python
富強文明民主和諧美麗
'''
with open('a.txt', 'r+', encoding='utf-8') as f:
content_list = f.readlines()
print(content_list)
'''輸出結果:
['人生苦短\n', '我用python\n', '富強文明民主和諧美麗']
'''
f.truncate(size)
從文件的首行首字符開始截斷,截斷文件爲 size 個字符,無 size 表示從當前位置截斷;截斷之後後面的所有字符被刪除,其中 Widnows 系統下的換行代表2個字符大小。
文件的修改
文件的數據全部都是儲存在硬盤上的。因此只能覆蓋,不能修改。我們常常看到的修改文件,都是模擬出來的。
具體的操作辦法是:將硬盤中存放的文件內容加載到內存中,在內存中修改內容,然後賦值到新的文件中,再由新文件覆蓋原文件。
示例:將文件的 “PHP” 全部替換成 “Python”
方式一: 將文件內容一次性全部讀入內存。如果文件很大,會很卡
import os # 調用系統模塊
with open('a.txt', 'r') as read_f, open('a.txt.swap', 'w') as write_f:
content = read_f.read()
content = content.replace('PHP', 'Python')
write_f.write(content)
os.remove('a.txt') # 刪除原文件
os.replace('a.txt.swap', 'a.txt') # 將新文件重命名爲原文件
方式二: 將文件逐行讀入內存修改。 這種方式有效避免文件過大而操作的卡頓問題。
import os # 調用系統模塊
with open('a.txt', 'r') as read_f, open('a.txt.swap', 'w') as write_f:
for line in read_f:
line = line.replace("PHP", "Python")
write_f.write(line)
os.remove('a.txt') # 刪除原文件
os.replace('a.txt.swap', 'a.txt') # 將新文件重命名爲原文件