ch01 6章中 1章目

ch01 — ファイルとは / バイナリ vs テキスト / 文字コード

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch01 — ファイルとは / バイナリ vs テキスト / 文字コード」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch01 — ファイルとは / バイナリ vs テキスト / 文字コード」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch01 — ファイルとは / バイナリ vs テキスト / 文字コード」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

プログラムから見たファイルは 「バイト列に、名前 (パス) が付いたもの」。ディスクに記録された 0 と 1 の連なりに、ファイル名と保存場所 (ディレクトリ) でアクセスできるようにしたもの。.txt.png.zip も中身は「バイトの並び」で、拡張子は 人間が「これは何のファイルか」を察するためのヒント に過ぎない。

中身の解釈で分かれるのが テキストファイル と バイナリファイル。テキストは「文字コードで意味付けされたバイト列」が並んだもの、バイナリは「画像やアーカイブなど特定アプリが解釈する独自フォーマット」。テキストを cat すると読める、バイナリを cat すると文字化けするのはこの違いから来る。

日本語が混じるテキストでは 文字コード が事故の温床。現代の Web 標準は UTF-8。古いシステムだと Shift_JIS / EUC-JP が混じり、間違うと文字化けする。さらに 改行コード (Unix/macOS は LF、Windows は CRLF) の違いも CSV パースで効いてくる。次の章から実際にファイルを読み書きする前に、「ファイル = バイト列 / 解釈は別レイヤー」をここで押さえる。

学習目標

  • 「ファイル = バイト列に名前 (パス) が付いたもの」と絵で言える
  • テキストファイルバイナリファイル の違いを 1 行で説明できる
  • 日本語が混ざるテキストは 文字コード (UTF-8 が標準) を意識する必要があると言える
  • 改行コード (LF / CRLF) で挙動が変わる場面があると知っている

ドリル

このチャプターにドリルはありません。 スライドを読み終わったら次の ch02-read-file/ に進んでください。

理由: 「ファイルとは何か」を 絵と言葉で押さえる のが目的。手を動かすのは ch02 から (file_get_contents で実際に読むところ) で行います。

確認してみる (任意)

エディタで適当な .txt ファイルを 1 つ作って、以下を観察すると理解が早い。

echo "こんにちは" > /tmp/hello.txt

# バイト列として見る
wc -c /tmp/hello.txt    # バイト数を出す (UTF-8 で「こんにちは」は 15 バイト + 改行)
xxd /tmp/hello.txt      # 16進ダンプ。1 バイトずつどう並んでいるかが分かる

# テキストとして見る
cat /tmp/hello.txt      # こんにちは

「ファイルの中身 = バイト列」「テキストエディタはそれを文字コード経由で 文字に解釈 している」という関係が腹落ちすれば OK。

解説スライド 全 8 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. ファイルとは / バイナリ vs テキスト / 文字コード

    Lesson 14 / Chapter 1

  2. ファイルって結局なに?

    hello.txt  ─┐
                ├─ ファイル名 (= ディスク上の場所を指す目印)
                └─ 中身 = ただのバイト列 (0 と 1 が並んだもの)
    • ファイル = バイト列 + 名前 (パス)
    • ディスク (HDD / SSD) 上に保存されていて、電源を切っても消えない
    • 「変数 ($x) はメモリ、ファイルはディスク」と覚える

    → PHP の役目は ディスク上のバイト列を読み出す / 書き込む

  3. テキストファイル vs バイナリファイル

    テキスト バイナリ
    中身 文字 として解釈できるバイト列 文字に直すと意味不明
    .txt / .csv / .json / .html / .php .png / .jpg / .pdf / .zip / .mp4
    エディタで開く 読める 文字化けする (専用ソフトで開く)
    PHP での扱い file_get_contents で文字列として fread でバイト数指定して読む

    file-io トピックで扱うのは テキスト系のみ (.txt / .csv)。画像・PDF などのバイナリは別トピック。

  4. 「文字コード」 = バイトを文字に翻訳するルール

    バイト: 0xE3 0x81 0x82
                    │
            UTF-8 で解釈
                    ▼
                  「あ」
    • UTF-8 : 今の標準 (Web も PHP も Mac も Linux も基本これ)
    • Shift_JIS : 古い Windows / Excel 由来 (CSV で時々遭遇)
    • EUC-JP : 古い UNIX 系 (ほぼ歴史的存在)

    → 違う文字コードで開くと 文字化け する。「UTF-8 で揃える」 が file-io トピックのお作法。

  5. 改行コード — LF と CRLF

    LF   = "\n"     (= 0x0A)         macOS / Linux の標準
    CRLF = "\r\n"   (= 0x0D 0x0A)    Windows / 一部の Web プロトコル
    場面 どっち
    PHP の \n LF
    php_eol (PHP_EOL 定数) 環境依存
    HTTP ヘッダ CRLF
    Excel が吐く CSV CRLF (Windows) / LF (Mac) どちらもあり得る

    fgetsCRLF も LF もまとめて読む が、末尾に改行が含まれることに注意 (rtrim($line) で外す)。

  6. PHP からファイルを触る基本パターン

    <?php
    // 読む (一発)
    $text = file_get_contents('/path/to/foo.txt');
    
    // 書く (一発)
    file_put_contents('/path/to/foo.txt', "hello\n");
    
    // 1 行ずつ読む (大きなファイル / 行単位処理向き)
    $fp = fopen('/path/to/foo.txt', 'r');
    while (($line = fgets($fp)) !== false) {
        echo $line;
    }
    fclose($fp);

    「一発で全部 (file_get_contents / file_put_contents)」と「1 行ずつ (fopen + fgets + fclose)」の 2 系統がある、と頭に入れる。

  7. file-io トピックの作法: 読みは固定 / 書きは一時ディレクトリ

    // 読み込み: drill 内の固定パスから (リポジトリにコミット済み)
    $path = __DIR__ . '/tests/data/hello.txt';
    $text = file_get_contents($path);
    
    // 書き込み: OS の一時ディレクトリへ (採点後に消える)
    $tmp = tempnam(sys_get_temp_dir(), 'dojo_');
    file_put_contents($tmp, "hi\n");
    unlink($tmp);  // 後始末
    • __DIR__ = この PHP ファイルがあるディレクトリ。cwd に依存せず安全
    • sys_get_temp_dir() = OS の一時領域 (Mac/Linux なら /tmp)
    • unlink($tmp) で必ず消す。CI で同じ drill を何度回しても汚れない
  8. このチャプターでできるようになること

    ✅ 「ファイル = バイト列 + 名前」と絵で言える ✅ テキスト / バイナリの違いを 1 行で言える ✅ UTF-8 / Shift_JIS の関係 (文字化けの正体) を言える ✅ LF / CRLF の違いと、PHP では \n (LF) が標準だと知っている ✅ 「読みは固定 / 書きは一時ディレクトリ」という file-io トピックの作法を理解した

    関連: ch02 で file_get_contents を使った実際の読み込みを扱う

1 / 8
📜 スライドを全部一気に読む(縦表示)

Lesson 14 / Chapter 1


ファイルって結局なに?

hello.txt  ─┐
            ├─ ファイル名 (= ディスク上の場所を指す目印)
            └─ 中身 = ただのバイト列 (0 と 1 が並んだもの)
  • ファイル = バイト列 + 名前 (パス)
  • ディスク (HDD / SSD) 上に保存されていて、電源を切っても消えない
  • 「変数 ($x) はメモリ、ファイルはディスク」と覚える

→ PHP の役目は ディスク上のバイト列を読み出す / 書き込む


テキストファイル vs バイナリファイル

テキスト バイナリ
中身 文字 として解釈できるバイト列 文字に直すと意味不明
.txt / .csv / .json / .html / .php .png / .jpg / .pdf / .zip / .mp4
エディタで開く 読める 文字化けする (専用ソフトで開く)
PHP での扱い file_get_contents で文字列として fread でバイト数指定して読む

file-io トピックで扱うのは テキスト系のみ (.txt / .csv)。画像・PDF などのバイナリは別トピック。


「文字コード」 = バイトを文字に翻訳するルール

バイト: 0xE3 0x81 0x82
                │
        UTF-8 で解釈
                ▼
              「あ」
  • UTF-8 : 今の標準 (Web も PHP も Mac も Linux も基本これ)
  • Shift_JIS : 古い Windows / Excel 由来 (CSV で時々遭遇)
  • EUC-JP : 古い UNIX 系 (ほぼ歴史的存在)

→ 違う文字コードで開くと 文字化け する。「UTF-8 で揃える」 が file-io トピックのお作法。


改行コード — LF と CRLF

LF   = "\n"     (= 0x0A)         macOS / Linux の標準
CRLF = "\r\n"   (= 0x0D 0x0A)    Windows / 一部の Web プロトコル
場面 どっち
PHP の \n LF
php_eol (PHP_EOL 定数) 環境依存
HTTP ヘッダ CRLF
Excel が吐く CSV CRLF (Windows) / LF (Mac) どちらもあり得る

fgetsCRLF も LF もまとめて読む が、末尾に改行が含まれることに注意 (rtrim($line) で外す)。


PHP からファイルを触る基本パターン

<?php
// 読む (一発)
$text = file_get_contents('/path/to/foo.txt');

// 書く (一発)
file_put_contents('/path/to/foo.txt', "hello\n");

// 1 行ずつ読む (大きなファイル / 行単位処理向き)
$fp = fopen('/path/to/foo.txt', 'r');
while (($line = fgets($fp)) !== false) {
    echo $line;
}
fclose($fp);

「一発で全部 (file_get_contents / file_put_contents)」と「1 行ずつ (fopen + fgets + fclose)」の 2 系統がある、と頭に入れる。


file-io トピックの作法: 読みは固定 / 書きは一時ディレクトリ

// 読み込み: drill 内の固定パスから (リポジトリにコミット済み)
$path = __DIR__ . '/tests/data/hello.txt';
$text = file_get_contents($path);

// 書き込み: OS の一時ディレクトリへ (採点後に消える)
$tmp = tempnam(sys_get_temp_dir(), 'dojo_');
file_put_contents($tmp, "hi\n");
unlink($tmp);  // 後始末
  • __DIR__ = この PHP ファイルがあるディレクトリ。cwd に依存せず安全
  • sys_get_temp_dir() = OS の一時領域 (Mac/Linux なら /tmp)
  • unlink($tmp) で必ず消す。CI で同じ drill を何度回しても汚れない

このチャプターでできるようになること

✅ 「ファイル = バイト列 + 名前」と絵で言える ✅ テキスト / バイナリの違いを 1 行で言える ✅ UTF-8 / Shift_JIS の関係 (文字化けの正体) を言える ✅ LF / CRLF の違いと、PHP では \n (LF) が標準だと知っている ✅ 「読みは固定 / 書きは一時ディレクトリ」という file-io トピックの作法を理解した

関連: ch02 で file_get_contents を使った実際の読み込みを扱う

完了にすると進捗に反映されます