原文標題為「2個java希爾排序示例」但內容實為 Python 文本編碼檢測。本文整理兩種常用檢測方式:檢查 BOM 標記、使用 cchardet 庫。
UTF-8 BOM 為開頭三個位元組:EF BB BF。可直接讀取檔案前 3 位元組判斷。
def is_utf8_bom(filepath: str) -> bool:
"""回傳 True 若檔案以 UTF-8 BOM 開頭"""
with open(filepath, 'rb') as f:
return f.read(3) == b'\xef\xbb\xbf'
優點:零依賴、極快、確定性強。
缺點:僅能檢測「有 BOM 的 UTF-8」;無 BOM 的 UTF-8、UTF-16、Big5、GBK 等均無法識別。
>>> import cchardet
>>> cchardet.detect(open('test.txt', 'rb').read())
{'encoding': 'UTF-8', 'confidence': 0.9900000095367432}
安裝:pip install cchardet(比 chardet 快 10~20 倍)。
def detect_encoding(filepath: str) -> dict:
with open(filepath, 'rb') as f:
raw = f.read()
return cchardet.detect(raw)
回傳欄位:encoding(偵測編碼)、confidence(信心度 0~1)、language(可選)。
import cchardet
def detect_file_encoding(filepath: str) -> str:
"""優先檢查 BOM,失敗再用 cchardet,最後預設 utf-8"""
# 1. BOM 檢查
with open(filepath, 'rb') as f:
bom = f.read(4)
if bom.startswith(b'\xef\xbb\xbf'): return 'utf-8-sig'
if bom.startswith(b'\xff\xfe'): return 'utf-16-le'
if bom.startswith(b'\xfe\xff'): return 'utf-16-be'
if bom.startswith(b'\xff\xfe\x00\x00'): return 'utf-32-le'
if bom.startswith(b'\x00\x00\xfe\xff'): return 'utf-32-be'
# 2. cchardet 推測
with open(filepath, 'rb') as f:
result = cchardet.detect(f.read())
encoding = result.get('encoding')
confidence = result.get('confidence', 0)
if encoding and confidence > 0.7:
return encoding.lower().replace('-', '_')
return 'utf-8' # 安全預設
f.read(100_000)。>>> import charset_normalizer
>>> charset_normalizer.from_path('test.txt').best().encoding
'UTF-8'
charset_normalizer 為 MIT 授權、無 C 擴充依賴、準確度高,已取代 `chardet` 成為諸多專案新寵。