ファイルシステムの基本構造
セクター・ブロック
- ストレージデバイス(HDDやSSD)は、物理的な単位でデータを保存します。この単位を「セクター」と呼び、通常は512バイトまたは4096バイトが1セクターに相当します。
- ファイルシステムはこれらのセクターをまとめて「ブロック」という単位で扱います。1ブロックのサイズは通常、4KBや8KBなどです。
メタデータ
ファイルシステムは、ファイルそのもの以外にも、以下の情報を管理します。
- ファイル名
- 作成日時や更新日時
- ファイルサイズ
- アクセス権限(誰が読み書きできるか)
- ファイルの場所(ストレージ上のどのブロックに保存されているか)
ディレクトリ構造
ファイルを整理するために階層的な構造を提供します。たとえば、Linuxではディレクトリ・Windowsではフォルダを使ってデータを分類できます。
インデックス
- ファイルシステムは、ストレージ上のどのブロックが特定のファイルに対応するかを記録しています。これをインデックスと呼びます。
- インデックスの管理方法にはいくつか種類があります
- FAT
- inode
ファイルシステムの動作原理
データの保存
- ユーザーが新しいファイルを保存するとき、ファイルシステムはストレージ上の空きブロックを検索して、データを書き込みます。
- また、そのファイルがどのブロックに保存されたかをインデックスとして記録します。
データの読み込み
- ファイルを開く際、ファイルシステムはインデックスを使ってファイルの場所を特定し、データを結合してユーザーに提供します。
データの削除
- ファイルを削除すると、ファイルのインデックスを削除してストレージ上のブロックを「空き」とマークします。しかし、データそのものは上書きされるまで残っています。
ファイルの拡張
- ファイルサイズが増える場合、追加のデータを保存するために新しいブロックを割り当て、インデックスを更新します。
ファイルシステムの主要な要素
ジャーナリング
- 書き込み中の障害によるデータ破損を防ぐ仕組み。
- 書き込み作業を始める前に、変更内容を「ジャーナル」に記録します。
- 障害が発生した場合、ジャーナルを参照してデータを復元します。
ファイル割り当て方法
ファイルがどのブロックに保存されるかを管理する方法には、以下の3つがあります。
連続割り当て
- ファイルを連続したブロックに保存します。
- メリット
- 読み書きが高速
- デメリット
- ファイルサイズが変わると断片化が発生
連結割り当て
- ファイルの各ブロックが次のブロックのポインタを持つ方式。
- メリット
- ファイルサイズの増減が柔軟
- デメリット
- 断片化が起こりやすく、アクセスが遅い
インデックス割り当て
- ファイルの全ブロックを指すインデックスを持つ方式。
- メリット
- ランダムアクセスが容易
- デメリット
- インデックスを管理するための追加のメモリが必要
断片化(フラグメンテーション)とその対策
断片化
ファイルのデータがストレージ上で連続して配置されず、分散する現象。これにより、読み書き速度が低下します。
対策
デフラグ(デフラグメンテーション)
- ファイルを再配置して連続性を回復する操作。
- 現代のSSDではほとんど不要(フラッシュメモリの特性により断片化の影響が少ないため)
ファイルシステムの基本操作Goサンプルコード
package main
import (
"fmt"
"os"
)
func main() {
// ファイルの作成
file, err := os.Create("sample.txt")
if err != nil {
fmt.Println("エラー:", err)
return
}
defer file.Close()
// データの書き込み
content := "ファイルシステムの仕組みを学びましょう!"
_, err = file.WriteString(content)
if err != nil {
fmt.Println("書き込みエラー:", err)
return
}
fmt.Println("ファイルにデータを書き込みました。")
// ファイルの読み込み
data, err := os.ReadFile("sample.txt")
if err != nil {
fmt.Println("読み込みエラー:", err)
return
}
fmt.Println("ファイルの内容:", string(data))
// ファイルの削除
err = os.Remove("sample.txt")
if err != nil {
fmt.Println("削除エラー:", err)
return
}
fmt.Println("ファイルを削除しました。")
}