前言

Python 不僅可存取文字檔案,也可存取如圖片、聲音等文件的二進位檔案。

在模式後面加上 b 就表示要以二進位模式開啟檔案,開啟二進位檔案不需要第三個 encoding 參數

模式說明
rb以二進位模式讀取
wb以二進位模式寫入(覆蓋)
ab以二進位模式附加
rt / wt文字模式(t可省略,這是預設值

為什麼二進位模式不需要 encoding

編碼的作用是「文字 ↔ 位元組」之間的翻譯。二進位模式處理的本來就是位元組,不需要翻譯,所以指定encoding反而會產生錯誤。

文字模式與二進位模式的差別

文字模式 t二進位模式 b
讀寫的資料型態str 字串bytes 位元組串列
需要 encoding✅ 需要❌ 不需要
換行字元處理會自動轉換原樣保留
適合文字檔 (.txt/.csv/.py)圖片、聲音、影片、壓縮檔

寫入二進位檔案

二進位檔案的資料是 bytes 位元組串列的格式,因此如果是字串必須以 encode 函式換為 bytes 位元組串列。

[簡例] 開啟<file.bin>二進位檔為寫入模式,並將資料寫入檔案中。(檔名:binarywrite.py

說明

  1. '''…'''定義多行字串。
  2. 第 6 行是關鍵encode("utf-8")str轉成bytes
  3. 開檔模式是'wb',沒有encoding參數。

忘記 encode 會怎樣

直接把字串寫入二進位檔會產生錯誤:

with open('file.bin', 'wb') as f:
    f.write("Hello")     # ❌ TypeError: a bytes-like object is required, not 'str'

看到 a bytes-like object is required 就是忘了encode()

讀取二進位檔案

讀取的二進位檔案資料是 bytes 位元組串列的格式,通常會以 decode 函式將位元組轉換為字串。

[簡例] 開啟<file.bin>二進位檔為讀取模式,並顯示讀取的資料。(檔名:binaryread.py

[結果]

Hello Python
中文字測試
Welcome

encode 與 decode 的關係

這兩個函式是一組的,方向剛好相反:

  str  ──── encode("utf-8") ────▶  bytes
  str  ◀─── decode("utf-8") ─────  bytes
函式方向用在
字串.encode("utf-8")strbytes寫入二進位檔前
位元組.decode("utf-8")bytesstr讀取二進位檔後

記法

encode = enter(進去變成機器看的 bytes)
decode = 解開(回到人看得懂的文字)

而且寫入用什麼編碼,讀取就要用什麼編碼 —— 這點跟 9. 檔案編碼與 BOM 處理 的道理完全一樣。

實務應用:複製圖片檔

二進位模式最常見的用途是處理非文字檔。例如複製一張圖片:

with open('photo.jpg', 'rb') as src:        # 讀二進位
    data = src.read()                       # 不用 decode!
 
with open('photo_copy.jpg', 'wb') as dst:   # 寫二進位
    dst.write(data)                         # 不用 encode!

圖片、聲音不要 decode

decode()是把位元組當成文字解讀。圖片本來就不是文字,硬要 decode 會產生UnicodeDecodeError

只有原本是文字、被轉成 bytes 的資料才需要 decode。 純二進位資料(圖片、影片、壓縮檔)直接讀寫即可。

實務上複製檔案有更簡單的做法

上面的程式只是為了示範二進位讀寫。真正要複製檔案時,用 8. shutil 檔案與目錄的複製搬移shutil.copy()一行就搞定,而且會處理得更完善。

常見錯誤

錯誤訊息原因解法
TypeError: a bytes-like object is required, not 'str'wb模式寫入字串encode()
TypeError: write() argument must be str, not bytesw模式寫入 bytes改用wb,或先decode()
ValueError: binary mode doesn't take an encoding argumentrb/wb模式加了encoding拿掉encoding參數
UnicodeDecodeError對圖片等非文字資料做decode()不要 decode,直接處理 bytes

相關主題與延伸閱讀