Python | ファイル操作など:read

Python
スポンサーリンク

概要(read は「ファイルから内容を取り出す」ための基本メソッド)

read は、open で開いたファイルオブジェクトから中身を取り出すメソッドです。テキストなら文字列、バイナリなら bytes を返します。読み込みには「全部読む」「一部だけ読む」「行ごとに読む」「反復で読む」の選択肢があり、サイズや用途に応じて使い分けます。必ず with 文で開き、encoding を明示するのが安全です。

# テキストを全部読む(UTF-8)
with open("notes.txt", "r", encoding="utf-8") as f:
    text = f.read()
Python

基本の読み込みパターン(ここが重要)

全部まとめて読む(f.read())

ファイル全体を一気に文字列(または bytes)で取得します。短いファイルなら簡単・確実ですが、巨大ファイルではメモリを圧迫します。

with open("small.txt", "r", encoding="utf-8") as f:
    content = f.read()
Python

サイズ指定で部分読み(f.read(n))

引数に整数 n を渡すと、そのバイト(テキストモードでは内部バッファに応じた分)だけ読みます。ループで複数回呼べば、ストリーム的に扱えます。大きいファイルやネットワーク越しのストリームで有効です。

with open("large.log", "r", encoding="utf-8") as f:
    chunk = f.read(1024)  # まず 1024 文字(近似)だけ
    while chunk:
        # 処理...
        chunk = f.read(1024)
Python

行ごとに読む(f.readline / 反復)

1行ずつ読むなら f.readline()、より実務的には「for 行 in f」で反復する方法が高速・省メモリです。readlines() は「全行をリストに」読み込みますが、大きいファイルではメモリに載り切らない可能性があるため注意します。

# ベストプラクティス:行反復
with open("data.csv", "r", encoding="utf-8") as f:
    for line in f:
        cols = line.strip().split(",")
        # 行の処理...
Python

テキストとバイナリの違い(encoding とモードの深掘り)

テキストモード(”r”)は文字列、エンコーディングを必ず明示

テキストは「文字列」で返ります。環境依存の既定エンコーディングは事故のもとなので、原則 “utf-8” を指定しましょう。日本語を安全に扱う基本です。

with open("jp.txt", "r", encoding="utf-8") as f:
    s = f.read()
Python

バイナリモード(”rb”)は bytes、画像や圧縮は必ずこちら

画像、PDF、ZIP などはバイナリです。テキストモードでは壊れるので “rb” を使います。サイズ指定の read(n) と相性が良く、部分読みやコピーが簡単にできます。

with open("photo.jpg", "rb") as f:
    blob = f.read(4096)  # 4KB ずつ処理
Python

改行の扱い(newline)とプラットフォーム差

テキストモードは通常、OSごとの改行を自動吸収します。入出力の改行を統一したい場合は newline=”\n” を指定すると意図が明確になります。

with open("log.txt", "r", encoding="utf-8", newline="\n") as f:
    text = f.read()
Python

実務での読み込み設計(安全・効率・見通し)

巨大ファイルは「行反復」か「サイズ指定 read」で分割処理

全部読みは簡単ですが、大サイズでは危険です。行反復なら一定メモリで走り、サイズ指定 read はバイナリ処理に向きます。どちらも「処理と読み」を小さく回すのがコツです。

def stream_copy(src_path: str, dst_path: str, buf: int = 1 << 20):  # 1MB
    with open(src_path, "rb") as src, open(dst_path, "wb") as dst:
        chunk = src.read(buf)
        while chunk:
            dst.write(chunk)
            chunk = src.read(buf)
Python

文字コードエラー対策(エンコーディング・errors)

外部から来たファイルは文字コードが混在することがあります。どうしても読みたいなら errors=”replace” で置換しつつ進め、元データの品質改善が可能ならそちらを優先します。

with open("unknown.txt", "r", encoding="utf-8", errors="replace") as f:
    s = f.read()  # 変換できない文字は「�」に置換
Python

CSV/JSON は専用モジュールで読む(正確さと可読性)

プレーン read + split でも読めますが、カンマのエスケープや改行の埋め込みは罠です。csv/json を使うと安全です。

import csv, json

with open("data.csv", "r", encoding="utf-8", newline="") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

with open("data.json", "r", encoding="utf-8") as f:
    obj = json.load(f)
Python

例題で身につける(定番から一歩先まで)

例題1:設定ファイルを行ごとに読む(省メモリ・堅牢)

def load_kv(path: str) -> dict[str, str]:
    kv = {}
    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith("#"):
                continue
            k, v = line.split("=", 1)
            kv[k.strip()] = v.strip()
    return kv
Python

例題2:部分読みで末尾を読む(ログの tail)

def read_tail_bytes(path: str, last_bytes: int = 2048) -> bytes:
    with open(path, "rb") as f:
        f.seek(-min(last_bytes, f.seek(0, 2) or 0), 2)  # 末尾基準で移動
        return f.read()
Python

例題3:巨大 CSV を一行ずつ処理(速度とメモリのバランス)

def count_items(path: str) -> int:
    import csv
    total = 0
    with open(path, "r", encoding="utf-8", newline="") as f:
        for row in csv.reader(f):
            # 1行ごとに集計(例:列数)
            total += len(row)
    return total
Python

例題4:バイナリのハッシュを計算(サイズ指定 read)

import hashlib

def sha256_file(path: str, buf: int = 1 << 20) -> str:
    h = hashlib.sha256()
    with open(path, "rb") as f:
        chunk = f.read(buf)
        while chunk:
            h.update(chunk)
            chunk = f.read(buf)
    return h.hexdigest()
Python

まとめ

read は「何を、どれくらい、どうやって」読むかの選択がすべてです。短いファイルはまとめて read、長いファイルは行反復かサイズ指定 read。テキストは encoding を明示、バイナリは “rb” で bytes を扱う。改行のプラットフォーム差は newline で制御し、CSV/JSON は専用モジュールで安全に。with 文による自動クローズを徹底し、エラー対策と省メモリ設計を習慣化すれば、読み込み処理は安定し、実務の品質に届きます。

タイトルとURLをコピーしました