# 通知設計書 11-FileSystemWatcher.Created

## 概要

本ドキュメントは、.NET の `System.IO.FileSystemWatcher` クラスが提供する `Created` イベントについて、その設計仕様と実装詳細を記述した通知設計書である。

### 本通知の処理概要

FileSystemWatcher.Created イベントは、監視対象のディレクトリ内に新しいファイルまたはディレクトリが作成された際に発生するイベント通知機能を提供する。

**業務上の目的・背景**：ファイルシステムの変更をリアルタイムに検知することは、ファイル同期、自動バックアップ、ログ監視、データ取り込みパイプラインなど、多くのアプリケーションシナリオで必要とされる。Created イベントは、新規ファイルの到着を検知してトリガー処理を開始するための基盤機能として、ファイルドロップ方式のデータ連携やホットフォルダ監視などの業務要件を実現する。

**通知の送信タイミング**：監視対象ディレクトリ（Path プロパティで指定）内で、新しいファイルまたはディレクトリが作成された瞬間にイベントが発生する。IncludeSubdirectories が true の場合、サブディレクトリ内での作成も検知対象となる。

**通知の受信者**：FileSystemWatcher インスタンスの Created イベントにハンドラを登録したアプリケーションコード。SynchronizingObject プロパティが設定されている場合、指定されたスレッドコンテキストでハンドラが呼び出される。

**通知内容の概要**：FileSystemEventArgs オブジェクトとして、変更種別（WatcherChangeTypes.Created）、作成されたファイル/ディレクトリの名前（Name）、フルパス（FullPath）が通知される。

**期待されるアクション**：受信者は通知を受け取り後、作成されたファイルの処理（読み取り、移動、変換など）、ログ記録、他システムへの連携通知、UIの更新などの業務処理を実行することが期待される。

## 通知種別

アプリ内通知（イベント通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（ThreadPool経由） |
| 優先度 | 中（通常のイベント配信） |
| リトライ | なし（イベントは一度のみ配信） |

### 送信先決定ロジック

Created イベントに登録された FileSystemEventHandler デリゲートが送信先となる。複数のハンドラが登録されている場合、マルチキャストデリゲートとして順次呼び出される。SynchronizingObject が設定されている場合は BeginInvoke 経由で非同期呼び出しが行われる。

## 通知テンプレート

### イベント引数

| 項目 | 内容 |
|-----|------|
| イベント型 | FileSystemEventArgs |
| sender | FileSystemWatcher インスタンス |
| ChangeType | WatcherChangeTypes.Created |

### イベントデータ構造

```csharp
public class FileSystemEventArgs : EventArgs
{
    public WatcherChangeTypes ChangeType { get; }  // Created
    public string FullPath { get; }                 // 作成されたファイル/ディレクトリのフルパス
    public string? Name { get; }                    // 作成されたファイル/ディレクトリの名前
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| ChangeType | 変更種別 | inotify/ReadDirectoryChangesW からのイベント種別 | Yes |
| FullPath | フルパス | 監視ディレクトリパス + ファイル名 | Yes |
| Name | ファイル/ディレクトリ名 | inotify イベントの name フィールド | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| OS通知 | ファイル/ディレクトリ作成 | EnableRaisingEvents == true かつ Filter/Filters にマッチ | 監視対象ディレクトリ内での新規作成を検知 |
| OS通知 | IN_CREATE (Linux) | EnableRaisingEvents == true | Linux inotify による作成イベント |
| OS通知 | IN_MOVED_TO (Linux) | EnableRaisingEvents == true かつ移動元が監視外 | 監視外からの移動は Created として扱う |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| EnableRaisingEvents == false | イベント発生が無効化されている |
| Filter/Filters 不一致 | ファイル名がフィルタパターンにマッチしない |
| NotifyFilters 不一致 | NotifyFilters.FileName/DirectoryName が設定されていない場合、該当種別は通知されない |
| Disposed | FileSystemWatcher が破棄済み |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[OS: ファイル作成検知] --> B{EnableRaisingEvents?}
    B -->|false| Z[通知スキップ]
    B -->|true| C{フィルタチェック}
    C -->|不一致| Z
    C -->|一致| D[FileSystemEventArgs 生成]
    D --> E{SynchronizingObject?}
    E -->|null| F[直接ハンドラ呼出]
    E -->|設定あり| G[BeginInvoke経由]
    F --> H[OnCreated 実行]
    G --> H
    H --> I[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（ファイルシステム通知のためデータベースを使用しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| InternalBufferOverflowException | 内部バッファがオーバーフローした場合 | Error イベントで通知、バッファサイズ増加を検討 |
| ObjectDisposedException | 破棄後のアクセス | アプリケーション側でライフサイクル管理 |
| ArgumentException | 無効なパス指定 | 監視開始前にパス検証 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし（イベントはリトライされない） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（OSイベント依存） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間監視可能）

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

- ファイルパスにはファイルシステムのアクセス権限が適用される
- 監視対象ディレクトリへの読み取り権限が必要
- Linux では inotify インスタンス数とウォッチ数にユーザーごとの制限がある（/proc/sys/fs/inotify/max_user_instances、/proc/sys/fs/inotify/max_user_watches）

## 備考

- Windows と Linux で内部実装が異なる（Windows: ReadDirectoryChangesW、Linux: inotify）
- 高頻度のファイル作成では、イベントの重複や欠落が発生する可能性がある
- ネットワークドライブでの監視は信頼性が低下する場合がある

---

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

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、イベント通知で使用されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FileSystemEventArgs.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs` | イベント引数のデータ構造。ChangeType、FullPath、Name プロパティの実装 |
| 1-2 | WatcherChangeTypes.cs | `src/libraries/System.IO.FileSystem.Watcher/ref/System.IO.FileSystem.Watcher.cs` | Created を含む変更種別の列挙型定義 |

**読解のコツ**: FileSystemEventArgs は EventArgs を継承しており、Combine メソッドでディレクトリとファイル名からフルパスを構築している点に注目。

#### Step 2: エントリーポイントを理解する

処理の起点となる FileSystemWatcher クラスのイベント定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FileSystemWatcher.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs` | Created イベントの定義と OnCreated メソッドの実装 |

**主要処理フロー**:
1. **行 272-282**: Created イベントの add/remove アクセサ定義
2. **行 473-476**: OnCreated メソッドによるイベント発火
3. **行 486-496**: InvokeOn メソッドによる SynchronizingObject 考慮のハンドラ呼び出し
4. **行 439-447**: NotifyFileSystemEventArgs メソッドでフィルタマッチング後にイベント発火

**読解のコツ**: _onCreatedHandler フィールドがデリゲートチェーンを保持し、InvokeOn メソッドで SynchronizingObject の有無によって呼び出し方法が分岐する点に注目。

#### Step 3: Linux 実装を理解する

Linux 環境での inotify を使用した実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | Linux 固有の inotify 実装 |
| 3-2 | Interop.INotify.cs | `src/libraries/Common/src/Interop/Linux/System.Native/Interop.INotify.cs` | inotify システムコールのP/Invoke定義 |

**主要処理フロー**:
- **行 679-681 (Linux.cs)**: IN_CREATE イベント受信時に WatcherEvent.Created を生成
- **行 700-701 (Linux.cs)**: IN_MOVED_TO で移動元が見つからない場合も Created として処理
- **行 963 (Linux.cs)**: WatcherEvent.Created ファクトリメソッドの定義

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

```
FileSystemWatcher.Created イベント
    │
    ├─ OnCreated(FileSystemEventArgs e)
    │      └─ InvokeOn(e, _onCreatedHandler)
    │             ├─ [SynchronizingObject == null] handler(this, e)
    │             └─ [SynchronizingObject != null] syncObj.BeginInvoke(handler, ...)
    │
    └─ NotifyFileSystemEventArgs(WatcherChangeTypes.Created, name)
           ├─ GetHandler(changeType) → _onCreatedHandler
           ├─ MatchPattern(name) → フィルタチェック
           └─ InvokeOn(new FileSystemEventArgs(...), handler)
```

### データフロー図

```
[入力]                    [処理]                           [出力]

Linux inotify           INotify.ProcessEvent()
IN_CREATE event  ───▶   NotifyFileSystemEventArgs()  ───▶  FileSystemEventHandler
                        FileSystemEventArgs生成              デリゲート呼び出し
                              │
                              ▼
                        OnCreated()
                              │
                              ▼
                        InvokeOn()
                              │
                              ▼
                        [SynchronizingObject判定]
                              │
                 ┌────────────┴────────────┐
                 ▼                         ▼
          直接呼び出し              BeginInvoke経由
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| FileSystemWatcher.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs` | ソース | メインクラス、Created イベント定義 |
| FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | ソース | Linux 固有実装（inotify） |
| FileSystemEventArgs.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs` | ソース | イベント引数クラス |
| FileSystemEventHandler.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventHandler.cs` | ソース | イベントハンドラデリゲート定義 |
| Interop.INotify.cs | `src/libraries/Common/src/Interop/Linux/System.Native/Interop.INotify.cs` | ソース | inotify P/Invoke 定義 |
| Strings.resx | `src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx` | リソース | エラーメッセージ文字列 |
