Python 常見檔案 / 資料夾操作

Posted on  Dec 13, 2018  in  Python 程式設計 - 初階  by  Amo Chen  ‐ 2 min read

年紀越大越容易金魚腦發作,有些東西不記錄成文章就特別容易忘。

本文記錄 Python 幾種常用的檔案(包含壓縮檔)與資料夾操作,以供速查之用。

本文環境

  • python 3.6.5
  • requests 2.19.1

下載檔案

程式內會需要透過 HTTP 下載檔案進行處理,這時候可以用 requests 模組下載檔案,然後將檔案的內容(content)直接寫入到檔案中:

import os
import requests


resp = requests.get(url)
file_path = os.path.join('/tmp', os.path.basename(url))
with open(file_path, 'wb') as file:
    file.write(resp.content)

解壓縮 ZIP 檔

如果下載的檔案是個 ZIP 壓縮檔,可以用 Zipfile 模組進行解壓縮:

import os
from zipfile import ZipFile


unzip_dir = os.path.join('/tmp', 'unzip')
os.mkdir(unzip_dir)

with ZipFile(zip_filename) as zip_ref:
    print(zip_ref.namelist())
    zip_ref.extractall(unzip_dir)

上述範例 zip_ref.namelist() 會取得 ZIP 壓縮檔內的所有檔名,而 zip_ref.extractall(unzip_dir) 會將所有檔案解壓縮至 unzip_dir 資料夾內。

壓縮檔案

通常使用 AWS 等雲端服務,頻寬的使用也是收費的一環,所以透過網路傳輸檔案時不免要壓縮一下檔案,除了加速檔案傳輸外也可多少節省些頻寬花費,以下示範 ZIP 與 Tar.gz 2 種壓縮方式:

ZIP

from zipfile import ZipFile


with ZipFile('test.zip', 'w') as zip:
    zip.write('test.txt')

ZipFile 也提供多種不同的壓縮方式可以選擇:

  • zipfile.ZIP_STORED
  • zipfile.ZIP_DEFLATED
  • zipfile.ZIP_BZIP2
  • zipfile.ZIP_LZMA

此外更可透過 compresslevel 設定壓縮等級,不過不同的壓縮方法有不一樣的級別設定,需特別注意:

The compresslevel parameter controls the compression level to use when writing files to the archive. When using ZIP_STORED or ZIP_LZMA it has no effect. When using ZIP_DEFLATED integers 0 through 9 are accepted (see zlib for more information). When using ZIP_BZIP2 integers 1 through 9 are accepted (see bz2 for more information).

設定不同壓縮方法與壓縮等級範例:

with ZipFile('test.zip', 'w', compression=zipfile.ZIP_BZIP2, compresslevel=9) as zip:
    zip.write('test.txt')

Tar.gz

壓縮成 tar.gz 檔則是透過 tarfile 模組:

import tarfile


tar_gz = tarfile.open('sample.tar.gz', 'w:gz')
for name in ['test1.txt', 'test2.txt']:
    tar_gz.add(name)
tar_gz.close()

跟 ZipFile 不一樣的是 tarfile 的 filemode 可以用冒號( : )做為分隔並指定壓縮的演算法,例如上述的 w:gz 即是指用 gzip 方式進行壓縮。詳細請參閱 文件

建立資料夾

建立資料夾除了 os.mkdir 之外,還可以使用 os.makedirs

import os


path = '/tmp/a/b/c'
os.makedirs(path)

makedirs 會幫忙將路徑中不存在的資料夾也一併建立,上述範例就相當於 Linux 指令:

$ mkdir -p /tmp/a/b/c

建立 temp 資料夾

有時候程式 concurrency 執行時,需要各自暫時的資料夾以彼此隔離避免檔案同時被讀取,導致無法預期的錯誤。此種情境可以使用 tempfile 模組為每個 process / thread 取得暫時性的資料夾:

import tempfile


temp_dir = tempfile.mkdtemp(prefix='temp')
print(temp_dir)

此外,使用上需要注意的是 mkdtemp 並不會主動刪除資料夾,因此程式結束之前需自行刪除這些資料夾。

The user of mkdtemp() is responsible for deleting the temporary directory and its contents when done with it.

刪除資料夾

刪除資料夾可以運用 shutil 模組提供的 rmtree 函示,該函式會遞迴刪除該資料夾底下的所有檔案:

import os
import shutil


path = '/tmp/a/b/c'
os.makedirs(path)
shutil.rmtree(path)

走訪資料夾

走訪資料夾的功能由 os.walk 函示所提供:

import os

from os.path import join, getsize


for root, dirs, files in os.walk('./your/path'):
    print(root, dirs, files)

複製檔案

shutil 模組提供 2 種複製檔案的方式,分別為 shutil.copyshutil.copy2 其差別在於 shutil.copy2 會保留檔案中的 meta 資料(例如 permission bits, last access time, last modification time 等等):

import shutil


src = '/etc/profile'
dst = '/tmp/profile.backup'

shutil.copy(src, dst)

# or

shutil.copy2(src, dst)

重新命名檔案 / 資料夾

範例:

import os

src = '/tmp/profile.backup'
dst = '/tmp/profile'
os.rename(src, dst)

刪除檔案

範例:

import os


path = '/tmp/file.txt'
file = open(path, 'wb')
file.close()
os.remove(path)

References

https://docs.python.org/3/library/tarfile.html

https://docs.python.org/3/library/zipfile.html

https://docs.python.org/3/library/tempfile.html

https://docs.python.org/3/library/shutil.html

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!