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

Python
スポンサーリンク

概要(readline は「ファイルを1行ずつ取り出す」ための基本メソッド)

readline は、open で開いたファイルオブジェクトから「次の1行」を文字列(テキスト)または bytes(バイナリ)で返します。行末の改行はそのまま含まれます。大きなファイルでもメモリを節約しながら順番に処理できるのが強みです。必ず with 文で開き、encoding を明示するのが安全です。

# 1行ずつ読み込む最小例(UTF-8 のテキスト)
with open("todo.txt", "r", encoding="utf-8") as f:
    line = f.readline()
    while line:              # 空文字 '' で末尾(EOF)
        print(line.strip())  # 改行などの余分を除去
        line = f.readline()
Python

基本の動きと終了判定(ここが重要)

1行ずつ読み、末尾では空文字が返る

readline() は「次の行」を返し、ファイル末尾に達すると空文字 ” を返します。この性質を利用して while ループで最後まで読み進めます。

with open("log.txt", "r", encoding="utf-8") as f:
    while True:
        line = f.readline()
        if not line:  # '' になったら終了
            break
        process(line)
Python

改行は含まれるので、表示や比較前に整える

戻り値には末尾の “\n”(環境により “\r\n” が入っていたものが “\n” に正規化)を含みます。見た目の乱れや比較ミスを避けるため、strip() か rstrip(“\n”) を習慣にしましょう。

with open("names.txt", "r", encoding="utf-8") as f:
    for _ in range(3):
        print(f.readline().strip())  # 改行を除去して表示
Python

サイズ指定で「長すぎる行」を分割読みできる

readline(size) の size に上限を渡すと、その分だけを読み、残りは次回以降の readline で続きます。非常に長い行に対して安全な読み方です。

with open("big_line.txt", "r", encoding="utf-8") as f:
    chunk = f.readline(1024)  # 最大1024文字
    total = []
    while chunk and not chunk.endswith("\n"):
        total.append(chunk)
        chunk = f.readline(1024)
    total.append(chunk)  # 最後の改行を含む断片
    line = "".join(total)
Python

readline と他の読み方の使い分け(深掘り)

readline と行反復(for line in f)の違い

  • readline(): 明示的に「1行ずつ」取り出す。サイズ制限を使える。細かい制御向き。
  • for line in f: イテレータで効率よく行単位処理。最もシンプルで高速、実務の定番。
# 推奨:まずは行反復で十分
with open("data.csv", "r", encoding="utf-8") as f:
    for line in f:
        cols = line.rstrip("\n").split(",")
Python

readlines は「全行をリスト」に読み込む(大きなファイルは非推奨)

readlines() は一度にメモリへ載せるため、巨大ファイルに向きません。メモリ節約が必要なら readline や行反復を選びます。

# 小さなファイルならOKだが、巨大ファイルでは避ける
with open("small.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
Python

read は「全部まとめて」読む(検索や全体整形に向く)

全文検索・一括置換などでは read() が便利ですが、サイズが大きいとメモリ圧迫。行単位処理なら readline/反復が安全です。


テキストとバイナリの違い(encoding・改行・bytes)

テキストモードは文字列、encoding を必ず明示

日本語を安全に扱うため、原則 “utf-8″ を指定します。未知の文字コードでは errors=”replace” で応急処置も可能です。

with open("jp.txt", "r", encoding="utf-8", errors="replace") as f:
    print(f.readline().strip())
Python

バイナリモードは bytes を返す

画像・PDF・ZIP などは “rb” で開きます。改行はバイト値としてそのまま扱われ、テキストの正規化は行われません。

with open("photo.jpg", "rb") as f:
    head = f.readline()   # 改行までのバイト列(ない場合はファイルの先頭断片)
    print(type(head))     # <class 'bytes'>
Python

newline の統一で入出力を制御

テキストモードでは通常、OS差の改行が吸収されます。処理を統一したいなら newline=”\n” を指定すると意図が明確になります。

with open("log.txt", "r", encoding="utf-8", newline="\n") as f:
    print(f.readline())  # 常に '\n' ベースで扱える
Python

実務での設計と安全策(省メモリ・堅牢・見通し)

省メモリの基本線:1行ずつ処理してすぐ捌く

大きなCSV・ログは「読みながら処理」を徹底。中間データを溜めずに集計・フィルタ・出力へ流すと安定します。

def count_rows(path: str) -> int:
    n = 0
    with open(path, "r", encoding="utf-8", newline="") as f:
        while True:
            line = f.readline()
            if not line: break
            n += 1
    return n
Python

例外や欠損行への対処(スキップとログ)

空行や壊れた行に遭遇したら、strip して空ならスキップ、try/except でエラーを記録して前進するのが現場の鉄則です。

def sum_qty(path: str) -> int:
    total = 0
    with open(path, "r", encoding="utf-8") as f:
        while True:
            line = f.readline()
            if not line: break
            line = line.strip()
            if not line or line.startswith("#"):  # コメント・空行
                continue
            try:
                name, qty = line.split(",", 1)
                total += int(qty)
            except Exception as e:
                print("WARN:", e, "line=", line)
    return total
Python

専用モジュールの活用(CSV/JSON は標準ライブラリを使う)

テキストを自力で split するより、csv や json を使うとエスケープや改行埋め込みにも正確に対応できます。

import csv

with open("data.csv", "r", encoding="utf-8", newline="") as f:
    reader = csv.DictReader(f)
    for row in reader:     # 行ごとに辞書で受け取れる
        handle(row)
Python

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

例題1:設定ファイルの読み込み(1行ずつ堅牢に)

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

例題2:サイズ制限付き readline で長い行を安全に処理

def safe_read_line(path: str, chunk_size: int = 4096) -> str:
    with open(path, "r", encoding="utf-8") as f:
        parts = []
        s = f.readline(chunk_size)
        while s and not s.endswith("\n"):
            parts.append(s)
            s = f.readline(chunk_size)
        parts.append(s)
        return "".join(parts)
Python

例題3:バイナリの先頭行風データを取得(bytes で扱う)

def peek_until_newline(path: str, buf: int = 1024) -> bytes:
    with open(path, "rb") as f:
        data = f.readline(buf)  # 指定バイトまで、改行があればそこで止まる
        return data
Python

例題4:readline と行反復を組み合わせてスキップ実装

def skip_header_then_process(path: str) -> list[str]:
    out = []
    with open(path, "r", encoding="utf-8") as f:
        # ヘッダ1行だけ readline で読み飛ばす
        _ = f.readline()
        for line in f:  # 本体は行反復で効率良く
            out.append(line.strip().upper())
    return out
Python

まとめ

readline は「1行ずつ、確実に、メモリを節約して」読むための基本メソッドです。末尾の空文字で終了判定、改行は含まれるので strip を習慣に、長すぎる行は size 指定で分割。巨大ファイルでは行反復(for line in f)が最有力、細かい制御が必要なら readline を選ぶ。テキストは UTF-8 を明示、バイナリは “rb” で bytes を扱い、CSV/JSON は専用モジュールで正確に。この線を守れば、初心者でも読み込み処理が安定し、現場で通用する品質に一気に近づきます。

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