HOWTO · Python

Python でファイルが空かどうかを確認する

ファイルが空かどうかを確認する方法を学びます。 また、Python で空のファイルをチェックしているときに発生したさまざまな問題についても調べています。

このページの内容

0バイトのファイルにはバイトが含まれていません。ただし、構造化データでは「空」の意味が異なることがあります。CSVを読み込むと行がない場合があり、Excelブックにはシートにレコードがなくても書式やシートのメタデータが含まれていることがあります。知りたい内容に合った確認方法を選びましょう。ファイルサイズの確認で分かるのは通常ファイルにバイトがあるかどうかであり、テーブルの確認で分かるのは読み込んだテーブルに行があるかどうかです。

ファイルサイズで空かどうかを確認する

ファイルシステムが報告するサイズの単位はバイトです。通常ファイルのサイズが 0 なら、バイトは含まれていません。サイズが0以外でも、テキストファイルに意味のある内容があるとは限りません。空白文字、バイトオーダーマーク、アプリケーションが使わないデータだけが含まれている可能性もあります。「空白以外のテキストがない」ことを確認したい場合は、内容を読み込んでデコードしてから調べてください。

このサンプルは一時フォルダー内に入力ファイルを作り、コードブロックの実行が終わると削除します。Python標準ライブラリだけを使うため、別のデータファイルを用意したり、特定のマシンに依存するパスを変更したりせずにスクリプトへ貼り付けられます。確認結果は真偽値として返るので、条件分岐に使ったり、ログ出力関数に渡したりできます。次の例を実行してください。コード内の表示メッセージや出力ラベルは、コードとのバイト一致を保つため英語のままです。

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as folder:
    path = Path(folder) / "notes.txt"
    path.write_text("Ready to process.\n", encoding="utf-8")
    print(path.is_file())
    print(path.stat().st_size == 0)

一時ディレクトリを使うことで、特定のコンピューター上のフォルダーに依存しない例になっています。最初の確認ではパスが通常ファイルを指しているかを調べ、次にファイルサイズが0バイトかどうかを判定します。

pathlibでファイルを確認する

ファイルサイズを調べる前に Path.is_file() を使います。パスが存在しない場合や、通常ファイルではない場合は False を返します。実際のアプリケーションでは、path を入力として受け取ったパスに置き換えてください。Windowsのパスでは、バックスラッシュがエスケープ文字として解釈される場合にraw文字列を使います。コード内の表示メッセージや出力ラベルは、コードとのバイト一致を保つため英語のままです。

from pathlib import Path

path = Path("notes.txt")
if not path.is_file():
    print("The path is missing or is not a regular file.")
else:
    try:
        empty = path.stat().st_size == 0
    except OSError as error:
        print(f"Could not check the file: {error}")
    else:
        print(f"Empty: {empty}")

is_file() が成功したあとでも、ファイルが削除されたりアクセスできなくなったりする可能性があるため、サイズの取得を try の中に置いています。stat() が失敗した場合、この例はそのファイルシステムエラーを報告し、ファイルを空だとは扱いません。一度だけ確認するなら、Path.stat().st_size == 0 が直接的なサイズ判定です。os.path.getsize(path) == 0 も同様に使え、パス形式のオブジェクトを受け取ります。

CSVファイルに行があるか確認する

CSVは解析して読み込むテキストなので、ファイルのバイト数からレコード数を確実に判断することはできません。ヘッダーだけでデータ行がないファイルにもバイトはありますが、レコードは含まれません。一方、空行だけのCSVは、利用できるテーブルとして読み込めないことがあります。pandasの DataFrame.empty は、どちらかの軸の長さが0なら True になります。すべてのセルが空であることを意味するわけではありません。この方法を使うにはpandasをインストールしてください。

次の自己完結した例では、小さなCSVを作成してから読み込みます。解析できる列がない場合、pandas.read_csv() は pandas.errors.EmptyDataError を送出することがあります。この状態は、別の対応が必要なファイルの欠落、権限の問題、CSVの形式不正とは分けて処理してください。コード内の表示メッセージや出力ラベルは、コードとのバイト一致を保つため英語のままです。

from pathlib import Path
from tempfile import TemporaryDirectory

try:
    import pandas as pd
except ImportError:
    print("Install pandas to run this example.")
else:
    with TemporaryDirectory() as folder:
        path = Path(folder) / "records.csv"
        path.write_text("name\nAda\n", encoding="utf-8")
        try:
            table = pd.read_csv(path)
        except pd.errors.EmptyDataError:
            print("The CSV has no parseable columns.")
        else:
            print(table.empty)

Excelシートに行があるか確認する

.xlsx ファイルにはセルの値だけでなくブックの構造も含まれるため、ファイルサイズから特定のシートにレコードがあるかどうかは判断できません。シートを読み込み、結果のDataFrameを確認します。read_excel() は既定で最初のシートを読み込みます。別のシートにデータがある場合は sheet_name を指定してください。Excelファイルを読むにはpandasと、互換性のあるExcelエンジンが必要です。多くの .xlsx ファイルでは openpyxl などを使います。

受け取るブックに合わせてパスとシート名を変更してください。DataFrame.empty は行または列があるかを確認します。空のセルだけで構成された行も、行として数えられます。ブックに利用可能な行がなくても見出しがあれば、通常この確認で見つけたい状態として、列はあるが行は0のテーブルになることがあります。以下の存在確認では、すでにブックがない場合に分かりやすいメッセージを表示します。read_excel() が開く前にファイルがなくなる可能性もあるため、読み込み時には FileNotFoundError を別に処理します。コード内の表示メッセージや出力ラベルは、コードとのバイト一致を保つため英語のままです。

from pathlib import Path

try:
    import pandas as pd
except ImportError:
    print("Install pandas and an Excel engine to read a workbook.")
else:
    workbook = Path("data.xlsx")
    if not workbook.is_file():
        print("Provide the path to an existing workbook.")
    else:
        try:
            table = pd.read_excel(workbook, sheet_name="Sheet1")
        except FileNotFoundError:
            print("The workbook disappeared before it could be read.")
        except PermissionError:
            print("Permission denied while reading the workbook.")
        except (ImportError, ValueError) as error:
            print(f"Could not read the selected sheet or Excel engine: {error}")
        else:
            print(table.empty)

ファイルの欠落と読み込みエラーを処理する

すべての読み込み失敗を空ファイルとして扱うために、広範囲に捕捉する except: 節を使わないでください。パスが存在しない、アクセスが拒否された、入力形式が不正である、ファイルは有効だが行がない、という結果はそれぞれ異なります。通常ファイルでは is_file() で確認し、パスが変わる可能性やプロセスにアクセス権がない可能性がある場合は、stat() の周囲で OSError を捕捉します。pandasでは、解析できる列がないCSVを扱うときに EmptyDataError を捕捉し、その後 FileNotFoundError、PermissionError、パーサーまたはエンジンのエラーをアプリケーションの要件に応じて処理してください。開発中は予期しないエラーを見える状態にし、データが空だと黙って扱わないようにします。

大切なのは、何を測っているかを区別することです。バイト数を調べるときはファイルシステムを使い、テーブルやシートに行があるかを知りたいときはCSVやExcelデータを解析します。サイズが0以外であることも、すべて空欄の行があることも、有用なレコードがある証拠にはなりません。「利用可能」の基準は、そのファイルを使うアプリケーションに合わせて定義してください。