ファイルシステムとは、人が使うファイル名やパスを、ファイルを識別する管理情報と、内容を置くストレージ領域へ結び付ける仕組みです。画面上ではmemo.txtが1つの箱に見えますが、内部では「名前を探す」「対象を開く」「論理的な位置へ書く」「媒体へ永続化する」という複数の処理がつながっています。
したがって、「保存ボタンを押した=その瞬間にSSDへ書き終えた」「ファイル=連続した物理領域」という理解は正確ではありません。この記事では、テキストエディタでmemo.txtにAを追記して保存する一例を、パス探索から永続化まで途切れずに追います。

SSDの中に、フォルダ型の箱やmemo.txtという札がそのまま置かれているわけではありません。ファイルシステムが「名前から内容へたどれる対応関係」を作るから、同じファイルとして保存・再読込できます。
まず一枚で:名前を探してから、内容を永続化する
次の図は、/home/ken/Documents/memo.txtを開き、Aを追記して保存するときの基本モデルです。WindowsではC:\Users\Ken\Documents\memo.txtのように表記やAPIが変わりますが、「パスを探索して対象を開き、論理位置へ書き、キャッシュからストレージへ反映する」という骨格は共通しています。

write成功はキャッシュへの受付で返ることがあり、永続化要求の完了とは限りません。図中の「inode」「ページキャッシュ」「ファイル記述子」はLinux/POSIX系で理解しやすい実装例です。Windowsにはファイルハンドルとシステムキャッシュ、NTFSにはMFT、APFSには独自のオブジェクトやツリーがあります。名称やデータ構造が違っても、名前空間・ファイル識別・論理データ・割り当て・I/Oを対応付ける必要がある、という一般原理を先に押さえてください。
memo.txtは「1つの物理的な箱」ではない
エクスプローラーやFinderに見えるmemo.txtは、利用者向けの論理的な見え方です。ローカルストレージ上の一般的なファイルシステムでは、少なくとも次の対応関係が必要になります。
| 層 | memo.txtでの役割 |
重要な点 |
|---|---|---|
| 名前空間 | Documentsディレクトリ内のmemo.txtという名前 |
名前からファイルを識別する情報へたどる |
| ファイルの管理情報 | 種類、サイズ、時刻、権限、データ位置の対応など | inodeやMFTレコードは、この役割を担う実装例 |
| 論理データ | 先頭から0、1、2…と数えるバイト列 | アプリは通常、媒体上の位置ではなくファイル内オフセットで読む・書く |
| 割り当て情報 | 論理範囲をストレージのブロックやextentへ対応付ける | 複数の離れた領域へ分かれることも、まだ割り当てられていない範囲があることもある |
ファイル名は、内容そのものではない
まず区別したいのは、名前とその名前が参照するファイルです。たとえばext4の公式資料では、ディレクトリエントリが名前をinode番号へ対応付けます。同じinodeを複数のディレクトリエントリから参照できるため、ハードリンクでは1つのファイルに複数の名前を付けられます。
これはext4の具体例ですが、「名前の管理」と「ファイルの管理情報」を分けて考える助けになります。名前を変更するrenameで、内容の全バイトを別の場所へコピーする必要がない場合があるのも、この分離があるからです。
inodeは一般名ではなく、実装例
LinuxのVFSでは、ディレクトリエントリがinodeオブジェクトを指し、inodeがファイルの種類、権限、時刻、サイズやデータへの操作を表します。しかし、すべてのOSやファイルシステムが同じ形のinodeを媒体へ保存するわけではありません。
NTFSではMFT(Master File Table)のエントリ内、またはMFTが記述する外部領域に、サイズ、時刻、権限、データ内容などが格納されます。APFSにも独自のファイルシステムオブジェクトとツリーがあります。この記事では、これらをまとめて「ファイルを識別し、その属性と内容への対応を持つ管理情報」と呼びます。
ファイルの連続性は「論理上」の話
アプリから見る通常のファイル内容は、先頭から順番に並ぶバイト列です。エディタが「末尾へAを追加する」ときは、SSDのセル番号ではなく、ファイル内のどのオフセットへ何バイト書くかを指定します。
ファイルシステムは、その論理範囲をストレージの割り当て単位へ変換します。複数の連続ブロックをまとめた対応をextentと呼ぶ実装もあり、ext4ではextent treeが論理ブロックとデータブロックを対応付けます。ただし、1つのファイルが媒体上の1本の連続領域に置かれる保証はありません。断片化、遅延割り当て、スパースファイル、コピーオンライトなどにより、論理的な並びと割り当ては異なります。
パスは「保存場所の文字列」ではなく、探索手順
/home/ken/Documents/memo.txtを1本の住所として一気に照合するのではありません。OSは起点を決め、区切られた名前を前から順に解決します。
/から探索を開始する。- ルートディレクトリで
homeという名前を探し、対応するディレクトリを得る。 - その中で
ken、次にDocumentsを探す。 Documentsの中でmemo.txtを探し、対応するファイルの管理情報へ到達する。- 各段階で、存在、ディレクトリであるか、探索権限、シンボリックリンクやマウント境界などを必要に応じて処理する。
Linux VFSの資料では、パス名をディレクトリエントリキャッシュから探索し、不足があれば対象ファイルシステムのlookup処理を使ってinodeを読み込みます。キャッシュは探索を速くするための仕組みであり、「キャッシュにない=ファイルがない」という意味ではありません。
絶対パスと相対パスの違いは「探索の起点」
絶対パスは、ルートやボリュームなど決められた起点から書きます。WindowsならC:\Users\Ken\Documents\memo.txt、Linuxなら/home/ken/Documents/memo.txtです。相対パスは、現在の作業ディレクトリなど別途定まった起点から書きます。いまDocumentsにいるなら、memo.txtだけでも探索できます。
つまり、相対パスは情報が欠けた絶対パスではなく、起点を別の状態から受け取る表現です。.は現在位置、..は親を表す場面があります。実際のディレクトリ移動や一覧表示は、コマンドプロンプト入門のcd、dir、mkdirにつながります。WindowsのPATHのようにパスを設定値として使う例は、Windowsの環境変数で確認できます。
open後は、パスではなくハンドルで操作する
パス探索が成功して権限も認められると、OSは開いた対象を表すハンドルをアプリへ返します。POSIXのopenではファイル記述子(file descriptor)を返し、WindowsのCreateFileではファイルハンドルを返します。名称や型は違いますが、どちらも以後の読み書きで「すでに開いた対象」を参照するための窓口です。
POSIXのopenは、ファイルとopen file descriptionを結び、その説明を参照するファイル記述子を作る操作として定義されています。Linux VFSでは、開いたファイルを表すカーネル内のstruct fileがプロセスのファイル記述子表へ登録されます。

ここが大きな転換点です。パスは「対象を見つけて開くまで」に使い、開いた後のwriteは通常、そのハンドルとファイル内オフセットを使います。毎回パスを最初から探索しているわけではありません。
この分離があるため、POSIX系では開いた後に名前が変更されても、既存のファイル記述子は同じ開いた対象を参照し続けます。また、最後の名前がunlinkされても、開いている記述子が残る間はファイルの資源が直ちに回収されないことがあります。Windowsでは共有モードや削除保留など規則が異なりますが、「名前」と「開いた対象」は同一概念ではありません。
アプリのAPI呼び出しが、どのように保護されたOS処理へ渡るかはシステムコールの解説で詳しく扱います。
保存ボタンから媒体まで:Aはどこを通るのか
「保存」はOSが定めた1個の万能操作ではなく、エディタが組み立てる処理です。ここでは理解の土台として、開いているmemo.txtへAを書き足す一般的なバッファ付きI/Oを追います。実際には、文字コード、エディタの内部バッファ、既存内容の再生成、一時ファイルなどにより呼び出し回数は変わります。
1. 画面上のAは、まずエディタのメモリにある
キー入力されたAは文字コードに従うバイト列としてエディタのメモリへ置かれ、画面表示も更新されます。この時点では、ファイルシステム上のmemo.txtが変わったとは限りません。エディタは「未保存」の状態を自分で管理しています。
2. エディタがハンドルを使って書き込みを依頼する
エディタは、開いたファイルのハンドル、書き込むバイト列、長さ、位置などをOSへ渡します。POSIXのwriteは、ファイル記述子に対応するファイルへ、現在のファイルオフセットなどに基づいて指定バイト数の書き込みを試みる操作です。
3. 通常のバッファ付き書き込みでは、まずメモリ上のキャッシュが変わる
Linuxの一般的なバッファ付きI/Oでは、ファイル内容をメモリ上のページキャッシュで読み書きします。Aを含むページが更新されると、そのページは「ストレージ上の内容より新しい」という意味でdirty(変更済み)になります。Windowsにもシステム管理のファイルキャッシュがあり、変更データを後でディスクへ書き出します。
この段階でwriteが成功を返すことがあります。これは重要な成功ですが、通常は「OSが書き込みを受け付け、後で処理できる状態になった」という意味であり、必ずしも不揮発性媒体への到達を意味しません。キャッシュが必要な理由と、バッファ・キャッシュの違いはバッファの解説で掘り下げています。
4. ファイルシステムが論理位置を割り当て先へ対応付ける
追記によってファイルが大きくなるなら、ファイルシステムは空き領域を割り当て、ファイルの論理オフセットをブロックやextentへ対応付けます。サイズや更新時刻などのメタデータも更新対象になります。ただし、ext4の遅延割り当てのように、dirtyデータを書き戻す時点まで具体的な配置決定を遅らせる実装もあります。
5. writebackがストレージI/Oを発行する
OSはdirtyなキャッシュをいつまでもメモリだけに置けないため、バックグラウンド処理、メモリ圧力、一定時間の経過、明示的な同期要求などを契機にwriteback(書き戻し)します。ファイルシステムが論理範囲を保存先へ対応付け、OSのI/O層とデバイスドライバを通してストレージへ要求を渡します。
その下では、要求キュー、DMA、割り込みやポーリング、ストレージ制御装置、機器内キャッシュ、媒体が関わります。この「要求を出して、完了を待ち、通知で再開する」流れはI/O(入出力)の解説につながります。
6. 永続化が必要なら、明示的な同期を要求する
電源断後も取得できる状態まで必要なアプリは、OSとファイルシステムへ永続化を要求します。POSIXにはfsync、WindowsにはFlushFileBuffersなどがあります。Linuxのfsyncは、変更済みのファイルデータと関連メタデータをストレージへ送り、機器が転送完了を報告するまで待ちます。
ただし、新しく作った名前やrenameした結果までクラッシュ後に残すには、Linuxでは対象ファイルだけでなく親ディレクトリの同期も必要になる場合があります。さらに保証の最終範囲は、OS、ファイルシステム、マウント設定、機器のキャッシュ制御、ハードウェアが仕様どおり応答することに依存します。
| 時点 | Aの主な所在 |
言えること | まだ言えないこと |
|---|---|---|---|
| 入力直後 | エディタのメモリ | 画面上の編集状態が変わった | ファイルへ反映された |
write成功後 |
ページキャッシュ/システムキャッシュなど | OSが書き込みを受け付けた | 媒体へ永続化した |
| writeback完了後 | ストレージ側まで転送済み | 対象I/Oが完了した | 機器内の揮発キャッシュまで必ず空になった |
| 永続化要求の成功後 | 仕様が保証する不揮発性の範囲 | クラッシュ後も取得できるよう同期を完了した | 故障や仕様違反まで含めた絶対保証 |
安全な保存では、一時ファイルから名前を切り替えることがある
既存のmemo.txtを先頭から直接書き換えると、途中でアプリやOSが停止したとき、古い内容を失ったうえで新しい内容も途中、という状態になり得ます。そこでエディタは、次のようなsafe saveを採用することがあります。
- 同じディレクトリ、または同じファイルシステム内に一時ファイルを作る。
- 新しい内容を一時ファイルへ最後まで書く。
- 必要な耐障害性に応じて、一時ファイルを同期する。
renameやOS固有のreplace操作で、memo.txtという名前が新しいファイルを参照するよう切り替える。- 必要なら親ディレクトリも同期し、名前の切り替えを永続化する。
POSIXのrenameでは、置換先の名前が処理中に消えた状態を他プロセスへ見せず、旧ファイルまたは新ファイルのどちらかを参照させられます。WindowsのReplaceFileは、新しいファイルで既存ファイルを置き換え、元ファイルの属性やACLなどを引き継ぐ処理をまとめています。AppleもAPFSの特徴としてatomic safe-save primitivesを挙げています。
ジャーナリングは何を守り、何を必ずしも守らないか
ジャーナリングは、更新内容の一部を先にログへ記録し、クラッシュ後に完了済みの取引を再生または未完了分を破棄できるようにする仕組みです。主な狙いは、空き領域の管理、ディレクトリ、ファイルサイズなどのファイルシステム構造が更新途中の矛盾した状態で止まることを防ぐことです。
しかし、「ジャーナリング対応=保存ボタン直前の本文が必ず残る」ではありません。ext4の公式資料では、標準のdata=orderedモードは主にメタデータをジャーナルへ記録し、クラッシュ後のファイルデータブロックが常に期待どおりであることまでは保証しないと説明されています。data=journalのようにデータも扱う設定はありますが、性能と保証の範囲が変わります。
| 仕組み | 主に守るもの | 単独では保証しないもの |
|---|---|---|
| ジャーナリング/コピーオンライトのメタデータ更新 | クラッシュ後にファイルシステム構造を回復しやすくする | アプリの最新データが必ず永続化済みであること |
| 一時ファイル+rename/replace | 利用者が途中まで書かれた新内容を見る危険を減らす | データと名前が電源断後も残ること |
fsync/FlushFileBuffers等 |
変更をストレージへ同期するよう要求し、完了を待つ | 別ファイルや親ディレクトリの変更、故障・仕様違反まで含む絶対保証 |
この3つは競合する機能ではなく、守る問題が違います。堅牢な保存を設計するなら、「途中の内容を見せない」「ファイルシステム構造を壊さない」「必要なデータを永続化する」を分けて考えます。
よくある4つの誤解を、内部構造から直す
| 誤解 | 正確な理解 | そう言える理由 |
|---|---|---|
| ファイルは連続した物理領域である | アプリには連続した論理バイト列として見え、ファイルシステムが複数のブロックやextentへ対応付ける | 論理オフセットと割り当て先を分離して管理するから |
| 保存ボタンを押せば媒体反映まで完了する | アプリ内更新、write受付、writeback、機器内キャッシュのflushは別段階 |
キャッシュで待ち時間を減らし、後からまとめてI/Oできるから |
| 削除すればデータは即座に消滅する | 名前との対応を外し、資源を再利用可能にする処理が中心で、即時の安全消去とは限らない | POSIXでは開いた記述子が残る間、最後の名前を削除しても対象が存続し得る。回収・上書きの規則も実装ごとに異なるから |
| 拡張子が中身の形式を保証する | .txtは名前の一部であり、アプリ選択や推測の手掛かり。中身がテキストかは別途解釈・検証が必要 |
名前を.jpgへ変えても、バイト列をJPEG形式へ変換する処理は起きないから |
特に削除は、「見えなくする」「開いている参照を終える」「割り当てを解放する」「媒体上の痕跡を消す」が別段階です。機密データの消去では、通常の削除操作を安全消去とみなさず、媒体と暗号化方式に合う手段を選ぶ必要があります。
NTFS・ext4・APFSは、同じ役割の異なる実装
ファイルシステムの本質は製品名ではありません。NTFS、ext4、APFSはいずれも名前からデータへたどれる状態を作りますが、管理構造、更新方式、対応OS、権限、暗号化、スナップショット、互換性などが異なります。
| 例 | この記事の原理に対応する実装例 | 断定してはいけないこと |
|---|---|---|
| NTFS | MFTのエントリがファイル情報や、外部データ領域への対応を保持する。Windowsはファイルハンドルとシステムキャッシュを使う | inodeやext4のジャーナル方式がそのまま存在する、とは言えない |
| ext4 | ディレクトリエントリが名前をinode番号へ結び、inodeのextent treeなどが論理ブロックをデータブロックへ対応付ける | inode、ページキャッシュ、fsyncのLinuxでの挙動を全OS共通とは言えない |
| APFS | コピーオンライトのメタデータ、オブジェクトマップ、extent、クローン、スナップショット、atomic safe-save primitivesなどを備える | 「ジャーナリングしないから安全性が低い」など、更新方式の違いを単純な優劣へ置き換えられない |
外付けストレージの形式を選ぶときは、単に「新しい形式」を選ぶのではなく、利用するOS、機器間の互換性、必要な最大ファイルサイズ、権限、暗号化、障害復旧、取り外し方を確認します。ネットワーク越しにファイルを置く場合は、ローカルのファイルシステムだけでなく、通信、サーバー側キャッシュ、共有プロトコルも永続化経路へ加わります。配置方式の違いはNAS・SAN・DASの違いで確認できます。
まとめ:ファイルシステムは「名前・論理データ・媒体」をつなぐ
memo.txtにAを保存できるのは、ファイルシステムが単にファイルとフォルダを一覧表示するからではありません。パスの各名前を探索してファイルを識別し、ファイル内の論理位置を割り当て先へ変換し、キャッシュ上の変更をストレージI/Oへつなぎ、必要なら永続化まで完了させるからです。ファイルシステムとは、名前の世界と、論理的なバイト列と、実際の保存領域を一貫して結び付ける仕組みなのです。
