Python Tips: Python で BOM つき UTF-8 のファイルを探したい

Python で BOM 付き UTF-8 でエンコードされたファイルを探す方法についてです。

BOM 付き UTF-8 が何かについては過去記事で述べているので興味のある方はそちらをご覧ください:

ここでは特定のディレクトリの下に BOM 付きの UTF-8 ・ BOM なしの UTF-8 ・その他のエンコーディングのファイルが混在している状況を想定しています。その中から BOM 付き UTF-8 のファイルをリストアップしたいイメージです。

上の記事で述べたとおり、 BOM 付きの UTF-8 かどうかを見分けるには 'utf-8' で読み込んで先頭の文字が BOM を表す '\ufeff' かどうかをチェックすれば OK です。ファイルを順に見ていくには pathlib.Path.glob() あたりを使うのがシンプルでかんたんです。

サンプル:

"""Locates files with utf-8 with BOM in a directory.
"""

import sys
from pathlib import Path

ENCODING = 'utf-8'
BOM = '\ufeff'


def main():
    current_dir = Path('.')
    for path in current_dir.glob('**/*.*'):
        if path.is_dir():
            continue

        try:
            if has_bom(path):
                print(path)
        except UnicodeDecodeError:
            print(f'{path} is not encoded with {ENCODING}.', file=sys.stderr)
            continue


def has_bom(path: Path) -> bool:
    """指定されたファイルが BOM 付き UTF-8 かどうかを調べる"""
    try:
        with path.open(encoding=ENCODING) as f:
            line_first = f.readline()
            if line_first.startswith(BOM):
                return True
    except UnicodeDecodeError as e:
        raise

    return False


if __name__ == '__main__':
    main()

UTF-8 で読み込めないファイル(= UTF-8 以外のエンコーディングのファイル)があった場合は UnicodeDecodeError が上がるので適宜処理をします。