# 機能設計書: System.IO.FileSystem（ファイルシステム）

## 1. 機能概要

### 1.1 機能名
System.IO.FileSystem（ファイルシステム）

### 1.2 機能ID
FUNC-017

### 1.3 機能説明
.NET ランタイムにおけるファイルシステム操作機能を提供するライブラリ。ファイルの読み書き、作成、削除、コピー、移動、ディレクトリ操作、パス操作、ファイル属性管理など、OSのファイルシステム機能へのアクセスを提供する。同期・非同期両方のAPIをサポートし、クロスプラットフォームで動作する。

### 1.4 関連画面
- なし（基盤ライブラリのため直接的な関連画面は存在しない）

## 2. 機能要件

### 2.1 入力仕様

| 項目名 | データ型 | 必須 | 説明 |
|--------|----------|------|------|
| path | string | Yes | ファイル/ディレクトリパス |
| contents | string/byte[] | No | ファイル内容 |
| mode | FileMode | No | ファイルオープンモード |
| access | FileAccess | No | アクセスモード |
| share | FileShare | No | 共有モード |
| options | FileOptions | No | ファイルオプション |

### 2.2 出力仕様

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| string | string | ファイル内容（テキスト） |
| byte[] | byte[] | ファイル内容（バイナリ） |
| string[] | string[] | 行配列、ファイル/ディレクトリ一覧 |
| FileStream | FileStream | ファイルストリーム |
| bool | bool | 存在確認結果 |
| FileInfo | FileInfo | ファイル情報 |
| DirectoryInfo | DirectoryInfo | ディレクトリ情報 |

### 2.3 処理フロー

```
File.ReadAllText(path)
    │
    ▼
┌─────────────────────┐
│ Path.GetFullPath()  │
│ パス正規化          │
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│ FileStream作成      │
│ 内部バッファ確保     │
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│ OS ファイルAPI      │
│ (Win32/Unix)       │
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│ StreamReader       │
│ テキスト読み込み     │
└─────────────────────┘
    │
    ▼
文字列返却
```

## 3. 詳細設計

### 3.1 クラス構成

#### 3.1.1 主要クラス

| クラス名 | 責務 |
|----------|------|
| File | ファイル操作の静的メソッド群 |
| Directory | ディレクトリ操作の静的メソッド群 |
| FileInfo | ファイル情報とインスタンスメソッド |
| DirectoryInfo | ディレクトリ情報とインスタンスメソッド |
| FileStream | ファイルストリーム |
| Path | パス文字列操作 |
| FileSystemWatcher | ファイルシステム変更監視 |

### 3.2 File クラス（File.cs）

#### 3.2.1 定数とフィールド

```csharp
// File.cs: 22-27行目
private const int ChunkSize = 8192;
internal const int DefaultBufferSize = 4096;

// UTF-8 without BOM（File.cs: 25行目）
private static Encoding UTF8NoBOM => field ??= new UTF8Encoding(
    encoderShouldEmitUTF8Identifier: false,
    throwOnInvalidBytes: true);
```

#### 3.2.2 主要メソッド

##### 読み取り操作

```csharp
// テキスト読み込み
public static StreamReader OpenText(string path);
public static string ReadAllText(string path);
public static string ReadAllText(string path, Encoding encoding);
public static string[] ReadAllLines(string path);
public static IEnumerable<string> ReadLines(string path);

// バイナリ読み込み
public static byte[] ReadAllBytes(string path);
public static FileStream OpenRead(string path);
```

##### 書き込み操作

```csharp
// テキスト書き込み
public static StreamWriter CreateText(string path);
public static StreamWriter AppendText(string path);
public static void WriteAllText(string path, string? contents);
public static void WriteAllLines(string path, IEnumerable<string> contents);
public static void AppendAllText(string path, string? contents);

// バイナリ書き込み
public static void WriteAllBytes(string path, byte[] bytes);
```

##### ファイル操作

```csharp
// File.cs: 42-56行目
public static void Copy(string sourceFileName, string destFileName);
public static void Copy(string sourceFileName, string destFileName, bool overwrite)
{
    ArgumentException.ThrowIfNullOrEmpty(sourceFileName);
    ArgumentException.ThrowIfNullOrEmpty(destFileName);

    FileSystem.CopyFile(Path.GetFullPath(sourceFileName), Path.GetFullPath(destFileName), overwrite);
}

// 削除（File.cs: 81-85行目）
public static void Delete(string path)
{
    ArgumentNullException.ThrowIfNull(path);
    FileSystem.DeleteFile(Path.GetFullPath(path));
}

// 存在確認（File.cs: 91-118行目）
public static bool Exists([NotNullWhen(true)] string? path);

// 移動
public static void Move(string sourceFileName, string destFileName);
public static void Move(string sourceFileName, string destFileName, bool overwrite);
```

##### ファイルオープン

```csharp
// File.cs: 124-133行目
public static FileStream Open(string path, FileStreamOptions options);
public static FileStream Open(string path, FileMode mode);
public static FileStream Open(string path, FileMode mode, FileAccess access);
public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share);

// SafeFileHandle直接取得（File.cs: 165-171行目）
public static SafeFileHandle OpenHandle(string path,
    FileMode mode = FileMode.Open,
    FileAccess access = FileAccess.Read,
    FileShare share = FileShare.Read,
    FileOptions options = FileOptions.None,
    long preallocationSize = 0);
```

### 3.3 Directory クラス（Directory.cs）

#### 3.3.1 主要メソッド

```csharp
// ディレクトリ情報取得（Directory.cs: 16-26行目）
public static DirectoryInfo? GetParent(string path);

// ディレクトリ作成（Directory.cs: 28-37行目）
public static DirectoryInfo CreateDirectory(string path)
{
    ArgumentException.ThrowIfNullOrEmpty(path);
    string fullPath = Path.GetFullPath(path);
    FileSystem.CreateDirectory(fullPath);
    return new DirectoryInfo(path, fullPath, isNormalized: true);
}

// Unix権限付き作成（Directory.cs: 52-54行目）
[UnsupportedOSPlatform("windows")]
public static DirectoryInfo CreateDirectory(string path, UnixFileMode unixCreateMode);

// 一時ディレクトリ作成（Directory.cs: 63-69行目）
public static DirectoryInfo CreateTempSubdirectory(string? prefix = null);

// 存在確認（Directory.cs: 80-98行目）
public static bool Exists([NotNullWhen(true)] string? path);

// ファイル/ディレクトリ列挙（Directory.cs: 166-194行目）
public static string[] GetFiles(string path);
public static string[] GetFiles(string path, string searchPattern);
public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption);
public static string[] GetDirectories(string path);
public static IEnumerable<string> EnumerateFiles(string path);
public static IEnumerable<string> EnumerateDirectories(string path);
```

### 3.4 FileMode 列挙型

| モード | 値 | 説明 |
|--------|-----|------|
| CreateNew | 1 | 新規作成（存在時エラー） |
| Create | 2 | 作成または上書き |
| Open | 3 | 既存を開く（なければエラー） |
| OpenOrCreate | 4 | 開くまたは作成 |
| Truncate | 5 | 切り詰めて開く |
| Append | 6 | 追記モード |

### 3.5 FileAccess 列挙型

| アクセス | 値 | 説明 |
|----------|-----|------|
| Read | 1 | 読み取り |
| Write | 2 | 書き込み |
| ReadWrite | 3 | 読み書き |

### 3.6 FileShare 列挙型

| 共有 | 値 | 説明 |
|------|-----|------|
| None | 0 | 共有なし |
| Read | 1 | 読み取り共有 |
| Write | 2 | 書き込み共有 |
| ReadWrite | 3 | 読み書き共有 |
| Delete | 4 | 削除共有 |
| Inheritable | 16 | 子プロセス継承 |

### 3.7 FileOptions 列挙型

| オプション | 説明 |
|------------|------|
| None | なし |
| WriteThrough | 書き込みキャッシュバイパス |
| Asynchronous | 非同期I/O |
| RandomAccess | ランダムアクセス最適化 |
| DeleteOnClose | クローズ時削除 |
| SequentialScan | シーケンシャルアクセス最適化 |
| Encrypted | 暗号化 |

## 4. エラー処理

### 4.1 例外一覧

| 例外 | 発生条件 |
|------|----------|
| FileNotFoundException | ファイルが見つからない |
| DirectoryNotFoundException | ディレクトリが見つからない |
| IOException | I/Oエラー |
| UnauthorizedAccessException | アクセス権限がない |
| PathTooLongException | パスが長すぎる |
| ArgumentException | パスが不正 |
| ArgumentNullException | パスがnull |

### 4.2 エラーハンドリング方針
- File.Exists/Directory.Exists は例外をスローしない
- 操作メソッドは適切な例外をスロー
- 詳細なエラー情報は IOException.HResult で取得可能

## 5. セキュリティ考慮事項

### 5.1 パス検証
- パストラバーサル攻撃の防止
- Path.GetFullPath による正規化
- 相対パスの適切な処理

### 5.2 アクセス制御
- OS のアクセス制御に依存
- FileShare によるロック管理
- 一時ファイルの適切な削除

## 6. コードリーディングガイド

### 6.1 推奨読解順序

1. **エントリーポイント**
   - `File.cs`: ファイル操作の静的メソッド
   - **22-27行目**: 定数定義
   - **29-31行目**: OpenText
   - **42-56行目**: Copy メソッド
   - **81-85行目**: Delete メソッド
   - **91-118行目**: Exists メソッド

2. **ディレクトリ操作**
   - `Directory.cs`: ディレクトリ操作
   - **16-26行目**: GetParent
   - **28-37行目**: CreateDirectory
   - **80-98行目**: Exists

3. **ストリーム層**
   - `FileStream.cs`: ファイルストリーム
   - `FileStreamHelpers.cs`: ヘルパー

4. **プラットフォーム抽象化**
   - `FileSystem.cs`: プラットフォーム共通インターフェース
   - `FileSystem.Unix.cs`: Unix 実装
   - `FileSystem.Windows.cs`: Windows 実装

### 6.2 プログラム呼び出し階層図

```
File.ReadAllText(path)
    │
    ├── ArgumentException.ThrowIfNullOrEmpty(path)
    │
    ├── Path.GetFullPath(path)
    │
    └── InternalReadAllText(path, encoding)
            │
            ├── new FileStream(path, FileMode.Open, FileAccess.Read, ...)
            │       │
            │       └── SafeFileHandle.Open()
            │               │
            │               └── FileSystem.Open() [プラットフォーム固有]
            │
            └── new StreamReader(stream, encoding)
                    │
                    └── ReadToEnd()

File.Copy(source, dest, overwrite)
    │
    ├── ArgumentException.ThrowIfNullOrEmpty(source)
    ├── ArgumentException.ThrowIfNullOrEmpty(dest)
    │
    ├── Path.GetFullPath(source)
    ├── Path.GetFullPath(dest)
    │
    └── FileSystem.CopyFile(fullSource, fullDest, overwrite)
            │
            ├── [Windows] Interop.Kernel32.CopyFileEx()
            └── [Unix] Interop.Sys.CopyFile()
```

### 6.3 データフロー図

```
┌──────────────────┐
│ アプリケーション   │
│ File.ReadAllText │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ File クラス       │
│ パス検証・正規化   │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ FileStream       │
│ バッファ管理      │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ SafeFileHandle   │
│ ハンドル管理      │
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ FileSystem       │
│ プラットフォーム   │
│ 抽象化           │
└────────┬─────────┘
         │
    ┌────┴────┐
    ▼         ▼
┌────────┐ ┌────────┐
│Windows │ │Unix    │
│API     │ │Syscall │
└────────┘ └────────┘
```

### 6.4 読解のコツ

#### 6.4.1 partial class 構成
File/Directory クラスは partial で分割:
- コア機能: `File.cs`, `Directory.cs`
- 非同期メソッド: `File.Async.cs`（存在する場合）

#### 6.4.2 FileSystem クラス
プラットフォーム固有の実装を抽象化:
```csharp
internal static partial class FileSystem
{
    public static void CopyFile(string source, string dest, bool overwrite);
    public static void DeleteFile(string path);
    public static bool FileExists(string path);
    public static bool DirectoryExists(string path);
}
```

#### 6.4.3 例外をスローしない Exists
```csharp
// File.cs: 91-118行目
public static bool Exists(string? path)
{
    try
    {
        // 検証と正規化
        // ...
        return FileSystem.FileExists(path);
    }
    catch (ArgumentException) { }
    catch (IOException) { }
    catch (UnauthorizedAccessException) { }

    return false;
}
```

### 6.5 関連ファイル一覧

| パス | 種別 | 役割 |
|------|------|------|
| `src/libraries/System.Private.CoreLib/src/System/IO/File.cs` | ソース | ファイル操作 |
| `src/libraries/System.Private.CoreLib/src/System/IO/Directory.cs` | ソース | ディレクトリ操作 |
| `src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs` | ソース | ファイル情報 |
| `src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs` | ソース | ディレクトリ情報 |
| `src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs` | ソース | ファイルストリーム |
| `src/libraries/System.Private.CoreLib/src/System/IO/Path.cs` | ソース | パス操作 |
| `src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.cs` | ソース | プラットフォーム抽象 |
| `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs` | ソース | ファイル監視 |

## 7. 使用例

### 7.1 テキストファイル操作

```csharp
// 書き込み
File.WriteAllText("test.txt", "Hello, World!");

// 読み込み
string content = File.ReadAllText("test.txt");

// 行単位読み込み
foreach (string line in File.ReadLines("test.txt"))
{
    Console.WriteLine(line);
}

// 追記
File.AppendAllText("test.txt", "\nNew line");
```

### 7.2 バイナリファイル操作

```csharp
// 書き込み
byte[] data = new byte[] { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
File.WriteAllBytes("binary.dat", data);

// 読み込み
byte[] read = File.ReadAllBytes("binary.dat");
```

### 7.3 ディレクトリ操作

```csharp
// 作成
Directory.CreateDirectory("newdir/subdir");

// ファイル一覧
string[] files = Directory.GetFiles(".", "*.txt", SearchOption.AllDirectories);

// 列挙（遅延評価）
foreach (string file in Directory.EnumerateFiles(".", "*.cs"))
{
    Console.WriteLine(file);
}
```

### 7.4 FileStream による詳細制御

```csharp
using var fs = new FileStream("data.bin",
    FileMode.Create,
    FileAccess.Write,
    FileShare.None,
    bufferSize: 4096,
    FileOptions.Asynchronous);

await fs.WriteAsync(buffer);
await fs.FlushAsync();
```

## 8. テスト観点

### 8.1 単体テスト観点
- ファイル読み書きの正確性
- 各 FileMode/FileAccess/FileShare の動作
- 存在しないファイル/ディレクトリへの操作
- パス正規化の動作

### 8.2 結合テスト観点
- 大きなファイルの処理
- 並行アクセス時の動作
- ネットワークドライブでの動作

### 8.3 性能テスト観点
- バッファサイズの影響
- 同期/非同期の性能差
- 大量ファイル列挙の速度

## 9. 変更履歴

| バージョン | 日付 | 変更内容 |
|------------|------|----------|
| 1.0 | 2026-01-30 | 初版作成 |
