# 機能設計書 37-ファイルI/O

## 概要

本ドキュメントは、Julia Base ライブラリにおけるファイルI/O機能の設計を記述する。`open` / `close` / `read` / `write` / `readline` / `readlines` / `eachline` / `readdir` などのファイル操作を提供する。

### 本機能の処理概要

本機能は、ファイルの読み書きに関する高レベルインターフェースを提供する。`open` によるファイルオープン、`read`/`write` による読み書き、`readline`/`readlines`/`eachline` による行単位の読み取り等を含む。

**業務上の目的・背景**：ファイルI/Oはプログラミングにおける最も基本的な操作の一つであり、設定ファイルの読み込み、データの永続化、ログの書き出し、テキスト処理の入力源など、ほぼすべてのプログラムで使用される。Julia のファイルI/Oは `IOStream` を基盤とし、C ランタイムの ios ライブラリを通じてOS機能にアクセスする。

**機能の利用シーン**：テキストファイルの行単位読み取り、バイナリファイルの読み書き、設定ファイルのパース、データファイルの書き出し、do構文によるリソース安全なファイル操作。

**主要な処理内容**：
1. `open(filename, mode)` によるファイルオープン（各種モード対応）
2. `open(f, filename, mode)` による do 構文対応のリソース安全なファイル操作
3. `read(filename)` / `read(filename, String)` によるファイル全体の読み込み
4. `write(filename, data)` によるファイルへのデータ書き込み
5. `readline(io)` / `readlines(io)` / `eachline(io)` による行単位読み取り
6. `readuntil(io, delim)` による区切り文字までの読み取り
7. `IOStream` 構造体によるファイルベースストリーム管理
8. ファイルモード文字列（"r", "w", "a", "r+", "w+", "a+"）の解析

**関連システム・外部連携**：C ランタイムライブラリ（ios_* 関数群）、OS ファイルシステム。

**権限による制御**：OSのファイルパーミッションに従う。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | REPL | 主画面 | 対話的なファイル操作 |

## 機能種別

ファイルI/O操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | AbstractString | Yes | ファイルパス | ファイルの存在・権限チェック |
| mode | AbstractString | No | オープンモード（"r","w","a","r+","w+","a+"） | 有効なモード文字列 |
| read | Bool | No | 読み取り可能フラグ（keyword版） | - |
| write | Bool | No | 書き込み可能フラグ（keyword版） | - |
| create | Bool | No | ファイル作成フラグ | - |
| truncate | Bool | No | ファイル切り詰めフラグ | - |
| append | Bool | No | 追記フラグ | - |
| lock | Bool | No | ファイルロックフラグ | デフォルト: true |
| keep | Bool | No | eachline で改行を保持するか | デフォルト: false |

### 入力データソース

ファイルシステム上のファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| open結果 | IOStream | オープンされたファイルストリーム |
| read結果 | Vector{UInt8} / String | ファイルの内容 |
| readline結果 | String | 1行分のテキスト |
| readlines結果 | Vector{String} | 全行のテキスト配列 |
| eachline結果 | EachLine | 行イテレータ |

### 出力先

戻り値として呼び出し元に返却。write は指定ファイルに出力。

## 処理フロー

### 処理シーケンス

```
1. open(filename, mode)
   └─ モード文字列の解析（"r"->read, "w"->write+create+truncate 等）
   └─ ccall(:jl_open, ...) で C ランタイム経由のファイルオープン
   └─ IOStream オブジェクトの構築
   └─ finalizer で自動クローズを登録
2. open(f, filename, mode)
   └─ io = open(filename, mode)
   └─ try f(io) finally close(io) end
3. readline(io)
   └─ readuntil(io, '\n')
   └─ chomp（keep=false の場合）
4. eachline(io; keep)
   └─ EachLine イテレータを構築
   └─ iterate で readline を繰り返し呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始: open filename, mode] --> B[モード文字列解析]
    B --> C[ccall jl_open でファイルオープン]
    C --> D{成功?}
    D -->|No| E[SystemError をスロー]
    D -->|Yes| F[IOStream オブジェクト構築]
    F --> G[finalizer 登録]
    G --> H[return IOStream]

    I[open f, filename] --> J[io = open filename]
    J --> K[try: f io]
    K --> L[finally: close io]
    L --> M[return 結果]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | モード文字列 | "r"=読取, "w"=書込+作成+切詰, "a"=追記+作成, "r+"=読書, "w+"=読書+作成+切詰, "a+"=読追記+作成 | open(filename, mode) |
| BR-37-02 | do構文安全性 | open(f, ...) は finally で必ず close を実行 | open(f, ...) |
| BR-37-03 | readline の chomp | keep=false（デフォルト）の場合、末尾改行を除去 | readline |
| BR-37-04 | ファイルロック | lock=true（デフォルト）でファイルロックを取得 | open with lock |
| BR-37-05 | read(filename) | ファイル全体をバイト列として読み込み | read(filename) |
| BR-37-06 | read(filename, String) | ファイル全体を文字列として読み込み | read(filename, String) |

### 計算ロジック

該当なし。

## データベース操作仕様

該当なし。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | SystemError | ファイルが存在しない（読み取りモード） | ファイルパスを確認 |
| - | SystemError | 書き込み権限がない | ファイルパーミッションを確認 |
| - | ArgumentError | 無効なモード文字列 | 有効なモード文字列を使用 |
| - | EOFError | ファイル末尾で読み取り | eof() で事前チェック |

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。ファイルI/Oにはトランザクション機構はない。

## パフォーマンス要件

- IOStream はCの ios バッファ（128バイト）によりシステムコールの回数を削減
- `eachline` はイテレータベースで、大きなファイルでも全体をメモリに読み込まない
- `read(filename)` はファイルサイズを事前に取得してバッファを確保

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

- ファイルパスのバリデーションはOS任せ（パストラバーサル等はユーザー責任）
- ファイルロック機構（lock パラメータ）によりレースコンディションを緩和

## 備考

- `open` の do 構文（`open(f, filename)`）の利用がリソースリーク防止のために推奨される
- `IOStream` は finalizer によりGC時に自動クローズされるが、明示的な close が推奨
- `fdio` 関数でファイルディスクリプタから IOStream を作成可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | iostream.jl | `base/iostream.jl` | IOStream 構造体: handle, ios, name, mark, lock フィールド |

**読解のコツ**: `ios` フィールドは `NTuple{128, UInt8}` であり、C ランタイムの ios 構造体をインラインで格納している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | iostream.jl | `base/iostream.jl` | open 関数群: モード文字列版と keyword 版 |
| 2-2 | iostream.jl | `base/iostream.jl` | open(f, ...) の do 構文版: try-finally パターン |

#### Step 3: 読み書き操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | iostream.jl | `base/iostream.jl` | read/write via ccall (ios_readall, ios_write 等) |
| 3-2 | stream.jl | `base/stream.jl` | readline/readlines/eachline の実装 |

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

```
open(filename, mode)
    |
    +-- モード文字列解析
    +-- ccall(:jl_open, ...) -> IOStream
    +-- finalizer(close, io)

open(f, filename, mode)
    |
    +-- io = open(filename, mode)
    +-- try: result = f(io)
    +-- finally: close(io)
    +-- return result

readline(io)
    |
    +-- readuntil(io, '\n')
    +-- chomp(line) [keep=false]

eachline(io; keep)
    |
    +-- EachLine(io, keep=keep)
    +-- iterate -> readline(io)
```

### データフロー図

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

filename: String -------> open(filename, "r") -------> IOStream
                               |
                               +-> ccall(:jl_open)
                               +-> IOStream 構築

IOStream ----------------> readline(io) ---------------> String (1行)
                               |
                               +-> readuntil(io, '\n')
                               +-> chomp

IOStream ----------------> read(io) -------------------> Vector{UInt8}
                               |
                               +-> ccall(:ios_readall)

data: Any ----------------> write(filename, data) ------> ファイル
                               |
                               +-> open(filename, "w")
                               +-> write(io, data)
                               +-> close(io)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| iostream.jl | `base/iostream.jl` | ソース | IOStream 構造体と open/read/write の低レベル実装 |
| stream.jl | `base/stream.jl` | ソース | readline/readlines/eachline 等の高レベル関数 |
| io.jl | `base/io.jl` | ソース | IO 抽象型の基本インターフェース |
| iobuffer.jl | `base/iobuffer.jl` | ソース | IOBuffer（メモリバッファ、sprint等で使用） |
| file.jl | `base/file.jl` | ソース | ファイル操作（cp, mv, rm 等） |
| stat.jl | `base/stat.jl` | ソース | ファイル情報取得（filesize 等、read のバッファサイズ算出に使用） |
