Python基礎之文件操作

一.文件路徑

絕對路徑

絕對路徑指的是從盤符開始的,直接到達目標文件位置的目錄下的絕對位置。 絕對路徑完整的描述了文件位置。例如,在 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。 若要保證不亂碼,文件用什麼方式存儲的,就用什麼方式打開


文件的打開模式

  1. 打開文件的模式有(默認爲文本模式):
    r,只讀模式【默認模式,文件必須存在,不存在則拋出異常】
    w,只寫模式【不可讀;不存在則創建;存在則清空內容】
    a, 只追加寫模式【不可讀;不存在則創建;存在則只追加內容】

  2. 對於非文本文件,我們只能使用 b 模式,“b” 表示以字節的方式操作(而所有文件也都是以字節的形式存儲的,使用這種模式無需考慮文本文件的字符編碼、圖片文件的 jgp 格式、視頻文件的 avi 格式)
    rb
    wb
    ab
    注:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型,不能指定編碼

  3. **‘+’**模式(就是增加了一個功能)
    r+, 讀寫【可讀,可寫, 文件指針會放在文件的開頭】
    w+,寫讀【可寫,可讀, 文件不存在則創建文件,存在則從文件的開頭開始編輯】
    a+, 寫讀【可寫,可讀,文件不存在則創建文件,文件已存在則文件指針放在文件的結尾】

  4. 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')  # 將新文件重命名爲原文件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章