英語613639 views
数学講師2886227 views
世界の国564520 views
高校物理160203 views
中学英語811710 views
中学社会668760 views
高校国語788336 views
高校化学2924392 views
LaTeX962153 views
Computer368106 views
Help
Tools
NewsSpreadsheetCalendarSlidesTier ListPen ToolIllustrationCrayonPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsCross SectionsMotion PathMechanicsWavesLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic Theory

English

バイナリモードとテキストモードの内部動作の違い

Python でファイルを開くとき、"r""rb" で何が違うのか。単に「改行コードの扱い」だけではない、内部動作の根本的な違いを解説する。

モードによる違いの概要

テキストモード("r", "w")

バイト列を文字列にデコード/エンコードする。改行コードの変換も行う

バイナリモード("rb", "wb")

バイト列をそのまま扱う。変換は一切行わない

テキストモードの内部処理

テキストモードでファイルを読むと、以下の処理が自動的に行われる。

ディスクからバイト列を読み込む

エンコーディングに従って文字列にデコード

改行コードを統一(\r\n → \n)

Python の str オブジェクトとして返す

# テキストモード
with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()  # str 型
    print(type(content))  # <class 'str'>

バイナリモードの内部処理

バイナリモードでは変換が行われない。

ディスクからバイト列を読み込む

そのまま bytes オブジェクトとして返す

# バイナリモード
with open("data.txt", "rb") as f:
    content = f.read()  # bytes 型
    print(type(content))  # <class 'bytes'>

改行コードの変換

テキストモードでは OS に応じた改行コードの変換が行われる。

読み込み時

\r\n(Windows)や \r(古い Mac)を \n に統一する

書き込み時

\n を OS のネイティブ改行コードに変換する(Windows では \r\n)

# Windows で作成されたファイル(\r\n 改行)
# テキストモード
with open("windows.txt", "r") as f:
    content = f.read()
    print(repr(content))  # 'line1\nline2\n'(\r が消える)

# バイナリモード
with open("windows.txt", "rb") as f:
    content = f.read()
    print(repr(content))  # b'line1\r\nline2\r\n'(そのまま)

この変換を無効にするには newline="" を指定する。

# 改行変換を無効にする
with open("data.txt", "r", newline="") as f:
    content = f.read()  # \r\n がそのまま残る

エンコーディングの自動検出

テキストモードではエンコーディングを指定しないと、システムのデフォルトエンコーディングが使われる。

import locale

# デフォルトエンコーディングを確認
print(locale.getpreferredencoding())  # UTF-8 など

# 明示的に指定するのがベストプラクティス
with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()
Linux / macOS

デフォルトは通常 UTF-8

Windows

デフォルトは CP932(Shift_JIS)などロケール依存。Python 3.15 から UTF-8 がデフォルトになる予定

バッファリングの違い

テキストモードとバイナリモードでバッファリングの動作も異なる。

# バイナリモードは buffering=0 が可能(バッファなし)
with open("data.bin", "rb", buffering=0) as f:
    pass  # OK

# テキストモードは buffering=0 不可
try:
    with open("data.txt", "r", buffering=0) as f:
        pass
except ValueError as e:
    print(e)  # can't have unbuffered text I/O

テキストモードでバッファなしにできないのは、エンコーディング変換がバッファを必要とするためだ。

io モジュールの構造

Python 3 の io モジュールは、階層的な構造を持っている。

FileIO

OS レベルの低レベル I/O。バイト列をそのまま扱う。

BufferedReader / BufferedWriter

FileIO をラップしてバッファリングを提供。

TextIOWrapper

BufferedReader/Writer をラップしてエンコーディング変換と改行処理を提供。

import io

# バイナリモードの内部構造
with open("data.txt", "rb") as f:
    print(type(f))  # <class '_io.BufferedReader'>
    print(type(f.raw))  # <class '_io.FileIO'>

# テキストモードの内部構造
with open("data.txt", "r") as f:
    print(type(f))  # <class '_io.TextIOWrapper'>
    print(type(f.buffer))  # <class '_io.BufferedReader'>
    print(type(f.buffer.raw))  # <class '_io.FileIO'>

seek() と tell() の違い

テキストモードでは seek()tell() の動作が複雑になる。

# バイナリモードはバイト位置で動作
with open("data.txt", "rb") as f:
    f.seek(10)  # 10 バイト目に移動
    pos = f.tell()  # 10

# テキストモードはエンコーディング依存
with open("data.txt", "r", encoding="utf-8") as f:
    # UTF-8 では 1 文字 = 1〜4 バイト
    # seek(10) が 10 文字目とは限らない
    f.seek(0)  # 先頭への seek は常に安全
    pos = f.tell()  # 不透明な値(実装依存)

テキストモードでは seek(0) 以外の seek() は避けるべきだ。任意の位置に移動したいならバイナリモードを使う。

使い分けの指針

用途モード理由
テキストファイルテキスト文字列として扱える、改行が統一される
画像・音声バイナリ変換されると壊れる
JSON・XMLテキスト文字列データとして解析する
ZIP・PDFバイナリバイナリフォーマット
ログ出力テキスト人間が読む文字列
ネットワークデータバイナリプロトコルに従う必要がある

まとめ

テキストモードの特徴

エンコーディング変換、改行変換、str 型で扱う。人間が読むファイル向け。

バイナリモードの特徴

変換なし、bytes 型で扱う。機械的なデータや正確なバイト操作が必要な場合向け。

迷ったら

エンコーディングを明示してテキストモードを使う。バイナリデータならバイナリモード。