# python-magic:最實用的「以內容判斷文件類型」方法 當伺服器具備圖片上傳功能時,往往會遇到以下需求。 * 「`.png` 這個檔案真的 PNG 嗎?」 * 「先判斷這個檔案是圖片還是文件,再決定處理方式。」 * 「在使用 Pillow/OpenCV 等外部解析器之前,先確認檔案類型。」 此時最堅實的起點不是「副檔名」,而是「檔案內容」。 而「以內容判斷」最簡單的工具就是 `python-magic`。 --- ## python-magic 是什麼? `python-magic` 是一個將 C 語言函式庫 libmagic 包裝成 Python 可用的工具。libmagic 透過檢查檔案的「頭部(前幾個位元組)」等特徵來辨識檔案類型,這個功能在 Unix 的 `file` 指令中也能看到。 簡而言之: * `file`(Linux 指令)=「在終端機使用的介面」 * `libmagic` = 「核心引擎(判斷邏輯)」 * `python-magic` = 「在 Python 中呼叫 libmagic 的薄包裝」 本文將以 `python-magic` 為核心,結構化說明「這個引擎究竟如何判斷檔案類型」。 --- ## libmagic 的工作原理 ![libmagic 库工作原理图](/media/editor_temp/6/0d5baf67-d72a-4f8d-9f1b-e273eaaba587.png) libmagic 的核心概念很簡單: > 「讀取包含檔案類型判斷規則的資料庫,依照規則檢查檔案位元組,並給出最合理的結論。」 這個資料庫即為 **magic database**(魔法模式資料庫),`file`/libmagic 共同使用。通常以編譯後的二進位檔(`magic.mgc`)安裝在系統中。 ### 1) 「魔法檔」是規則集合 這些規則主要包含: * **要檢查的位置**(offset:檔案的哪個位元組) * **讀取方式**(type:位元組/字串/整數等) * **比較目標**(expected value/pattern) * **判斷結論**(message/MIME 等) `file` 的手冊也說明它在檢查「magic patterns」。規則逐行測試(offset/type/value/message),若符合則進一步進入更具體的子測試,形成「層級結構」。 想了解 Linux `file` 指令的詳細資訊,請點擊以下連結。 [了解 Linux file 指令](https://cmdbox.mikihands.com/file/) ### 2) 規則資料庫有「文字原始」與「編譯結果」 魔法資料庫原本是人類可讀的文字片段,為了效能,通常也提供編譯後的二進位資料庫(`.mgc`)。 ### 3) 目的:以內容判斷檔案類型 `file` 之所以被視為「以內容判斷檔案類型」的工具,已是長久以來的哲學。`python-magic` 就是把這個哲學「以一行 Python 代碼」帶進來的工具。 --- ## 如何使用 python-magic 常見的使用模式有兩種。 ### 1) 取得 MIME 類型(最實用) 適用於上傳處理、路由、日誌/指標。 ```python import magic mime = magic.from_file("upload.bin", mime=True) print(mime) # 例如: image/png ``` `python-magic` 以 libmagic 為基礎提供檔案類型辨識,功能與 `file` 指令相同,官方說明亦如此。 ### 2) 直接以位元組判斷(上傳流時更方便) 在將檔案寫入磁碟前,只需檢查上傳的前幾個位元組即可快速判斷。 ```python import magic with open("upload.bin", "rb") as f: head = f.read(4096) mime = magic.from_buffer(head, mime=True) print(mime) ``` (基於緩衝區的判斷特別適合作為「檔案寫入前的第一道過濾器」) --- ## 從開發者角度看其實用性 ### 1) 上傳驗證的第一道防線 * 不僅依賴副檔名 * 先確認「這個檔案能否被當作圖片處理」 ### 2) 處理流程的分流點 * 若是圖片 → 進入縮放/縮圖流程 * 若是 PDF/ZIP → 交給其他工作者 * 若是未知類型 → 隔離/拒絕/進一步驗證 ### 3) 在呼叫「重量級解碼器」前降低成本 Pillow 等解碼器雖強大,但呼叫本身會消耗記憶體/CPU,甚至擴大攻擊面。`python-magic` 可先判斷「是否值得進一步處理」。 > 重要實務提醒:libmagic 只是一個**推測/辨識**工具。若安全性是首要目標,仍需額外驗證(白名單、大小限制、沙盒解碼等)。 --- ## 小結:python-magic 是「以程式碼輕鬆取得檔案類型」的最佳選擇 * 不是用來處理圖片,而是告訴你「這個檔案應該怎麼對待」 * 引擎:`file`/libmagic * 判斷方式:規則資料庫 + 位元組檢查 * 在實務中,特別適合上傳驗證、路由決策、成本節省 掌握後,即使在缺乏其他庫的環境,也能構建「判斷 → 分流 → 安全防護」的流程。 --- ## 下一篇預告 * 解析 Pillow(PIL)的 `open()`、`load()`、`verify()` 各自保證什麼,何時使用,如何運作。 --- **相關文章** - [開發者眼中的圖片檔案結構:拆解圖片檔案](/ko/whitedec/2026/1/14/developer-view-image-file-common-structure/)