Try   HackMD

檔案系統操作

tags: python

目錄與檔案路徑

路徑的表達方式

  • 相對路徑:指相對於目前目錄的路徑,目前的目錄稱又稱為工作目錄

    例如:example目錄為目前目錄下有一個子目錄為example

  • 絕對路徑:由系統的根目錄開始表達,Linux和Windows表達方式有其差異

    Linux: /etc/httpd/config

    Windows: C:\Users\Administrator\Documents\File.txt

  • .:特殊目錄符號,代表目前的目錄

  • ..:特殊目錄符號,代表上一層目錄

os模組與os.path模組

Python內與目錄相關的模組為osos.path兩個模組,因為os.pathos內的子模組,所以只需要import os即可。

取得路徑
import os print(os.getcwd()) # 取得目前工作目錄 print(os.path.abspath('.')) # 取得目前目錄的絕對路徑 print(os.path.abspath('..')) # 取得目前目錄上一層目錄的絕對路徑 print(os.path.abspath('hello.txt')) # 取得目前目錄下指定檔案的絕對路徑 print(os.path.relpath('D:\\')) # 回傳目前目錄到D:\的相對路徑 print(os.path.relpath('D:\\Downloads')) # 回傳目前目錄到D:\Downloads的相對路徑 print(os.path.relpath('D:\\Downloads', 'hello.txt')) # 回傳目前目錄下hello.txt檔案到D:\Downloads的相對路徑

備註:

請記得在字串內,「\」字元需要使用轉譯符號,否則會被當成轉譯字元。

檢查路徑
import os print(os.path.exist('hello.txt')) # 檢查目前目錄下是否存在hello.txt檔案 print(os.path.isabs('D:\\Documents\\hello.txt')) # 檢查路徑是否為一個絕對路徑 print(os.path.isdir('repo')) # 檢查路徑是否為目錄 print(os.path.isfile('repo')) # 檢查路徑是否為檔案

說明:

路徑檢查相關函式回傳直皆為:True=存在、False=不存在

檔案與目錄操作

import os os.path.mkdir('sub') # 在目前的目錄下建立sub目錄 os.path.rmdir('sub') # 刪除目前目錄下的sub目錄 os.path.remove('file.txt') # 刪除目前目錄下的file.txt檔案 os.path.chdir('sub') # 將目前的工作目錄切換到sub目錄下

補充:

建議在進行目錄操作前,先呼叫os.path.exists()檢查是否存在,否則可能會因為建立一個已經存在的目錄而產生例外結束程式。

目錄與檔案的屬性與內容

import os

os.path.getsize('hello.txt')  # 取得hello.txt檔案大小(單位為bytes)
os.listdir()                # 列出目前目錄下的內容
os.listdir('D:\\Downloads') # 列出D:\Download目錄下的內容

目錄與檔案的屬性與內容(使用glob模組)

這個模組與os模組最大的差別是可以使用萬用字元「*」與「?」

import glob print(glob.glob('D:\\Download\\*.txt')) # 列出D:\Downloads目錄下所有附檔名為txt的檔案 print(glob.glob('D:\\Download\\?.txt')) # 列出D:\Downloads目錄下所有附檔名為txt,且主檔名只有一個字元的檔案

列出目錄以及目錄下所有子目錄內容

import os

for dir_name, sub_dir_names, filenames in os.walk():
    print(dir_name)      # 目前工作目錄名稱
    print(sub_dir_names) # 目前目錄下所有子目錄名稱
    print(file_names)    # 目前目錄下所有檔案名稱

讀寫檔案

開啟檔案

所有檔案操作都必須先透過open()函式開啟檔案並取得檔案物件後才能進行檔案操作。

檔案開啟模式:

模式 描述
t 文字模式 (預設)。
x 寫模式,新建一個檔案,如果該檔案已存在則會報錯。
b 二進位制模式。
+ 開啟一個檔案進行更新(可讀可寫)。
r 以只讀方式開啟檔案。檔案的指標將會放在檔案的開頭。這是預設模式。
rb 以二進位制格式開啟一個檔案用於只讀。檔案指標將會放在檔案的開頭。這是預設模式。一般用於非文字檔案如圖片等。
r+ 開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
rb+ 以二進位制格式開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。一般用於非文字檔案如圖片等。
w 開啟一個檔案只用於寫入。如果該檔案已存在則開啟檔案,並從開頭開始編輯,即原有內容會被刪除。如果該檔案不存在,建立新檔案。
wb 以二進位制格式開啟一個檔案只用於寫入。如果該檔案已存在則開啟檔案,並從開頭開始編輯,即原有內容會被刪除。如果該檔案不存在,建立新檔案。一般用於非文字檔案如圖片等。
w+ 開啟一個檔案用於讀寫。如果該檔案已存在則開啟檔案,並從開頭開始編輯,即原有內容會被刪除。如果該檔案不存在,建立新檔案。
wb+ 以二進位制格式開啟一個檔案用於讀寫。如果該檔案已存在則開啟檔案,並從開頭開始編輯,即原有內容會被刪除。如果該檔案不存在,建立新檔案。一般用於非文字檔案如圖片等。
a 開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
ab 以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
a+ 開啟一個檔案用於讀寫。如果該檔案已存在,檔案指標將會放在檔案的結尾。檔案開啟時會是追加模式。如果該檔案不存在,建立新檔案用於讀寫。
ab+ 以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。如果該檔案不存在,建立新檔案用於讀寫。
with open('test.txt') as file: # 開啟目前目錄下的test.txt檔案並 psss

補充:

開啟檔案時可以相對路徑或絕對路徑指定檔案位置。

檔案編碼

若沒有指定encoding參數,開檔時將採用 locale.getpreferredencoding() 的編碼設定,如果要強制指定使用UTF-8編碼,可以加上encoding參數來指定編碼,例如:

open('text.txt', encoding='uff-8')

讀取檔案

ㄧ次讀取全部檔案內容
with open('test.txt') as file: content = file.read() # 一次讀取全部檔案內容 print(content)
逐行讀取檔案內容
with open('test.txt') as file: for line in file: print(line)

另一種方式(使用readlines()方法)

with open('test.txt') as file: lines = file.readlines() for line in lines: print(line)

寫入檔案

當呼叫open()函式打開檔案時,預設只能讀取內容而無法寫入,因此如果要寫入內容到檔案,需要指定「w」模式才能人入資料到檔案。

開啟檔案為寫入模式(會清空原檔案內容)
with open('test.txt', 'w') as file: pass
開啟檔案為寫入模式(檔案內容會附加到原始檔案後面)
with open('test.txt', 'a') as file: pass
寫入字串到檔案
with open('test.txt', 'w') as file: file.write('Hello') file.write(' Python')

補充:

如果要寫入多行資料,需要加上「\n」來換行

檔案操作

shutil模組

Python提供了shutile用來操作檔案的複製、刪除、移動與修改名稱等等操作,要進行這些操作前需要引入shutil模組:

import shutil

檔案複製

import shutil shutil.copy('a.txt', 'b.txt') # 將目前目錄下的a.txt檔案複製為b.txt

目錄複製

import shutil shutil.copytree('a', 'b') # 將目前目錄下的a目錄複製成b目錄
  • 來源目錄要存在,否則會產生例外並結束程式
  • 可使用相對路徑或絕對路徑
  • 目錄下的子目錄和檔案都會一併被複製到新目錄下

檔案移動

import shutil shutil.move('a.txt', 'D:\\Documents') # 將目前目錄下的a.txt搬移到D:\Documents目錄下 shutil.move('a.txt', 'D:\\Documents\b.txt') # 將目前目錄下的a.txt搬移到D:\Documents目錄下,並改名為b.txt

補充:

在移動的過程中如果目的路徑有包含檔案名稱,則會一併修改檔案名稱

目錄移動

move()函式也可以用來進行目錄的移動

import shutil shutil.move('my-dir', 'D:\\Documents') # 將目前目錄下的my-dir子目錄移動到D:\Documents下 shutil.move('my-dir', 'D:\\Documents\my-dir-2') # 將目前目錄下的my-dir子目錄移動到D:\Documents下,並改名為my-dir-2

補充:

如果目的地的目錄不存在,則會將原始目錄更名為該名稱,達到改變目錄名稱的效果。

刪除空目錄

import shutil shutil.rmdir('hello') # 刪除hello這個空目錄

補充:

如果要刪除的目錄不是空的,則會刪除失敗。

刪除目錄和底下的所有內容

import shutil shutil.rmtree('hello') # 刪除hello目錄和底下所有的子目錄和檔案

注意:

刪除後無法復原,請小心使用。

練習

  1. 列出指定目錄下所有檔案的大小總和。

  2. 將指定目錄下的文字檔檔名前面都加上編號,例如:

    ​​​a.txt
    ​​​tr.txt
    ​​​obc.txt
    

    變成:

    ​​​01-a.txt
    ​​​02-tr.txt
    ​​​03-obc.txt