2019/10/08

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

Python で BOM 付き UTF-8 でエンコードされたファイルを特定のディレクトリの中から探す方法についてです。

UTF-8 の BOM とは何ぞやというお話は別記事で述べているので興味のある方はそちらをご覧ください:


ここでは特定のディレクトリの下に 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:
    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 が上がるので適宜処理をします。ここでは対象のファイル名を含むエラー文を標準エラーに出力しています。

以上です。

0 件のコメント: