# 機能設計書 44-一時ファイル

## 概要

Julia Base ライブラリにおける一時ファイルおよび一時ディレクトリの作成・管理を提供する機能の設計書である。

### 本機能の処理概要

**業務上の目的・背景**：一時的なデータの保存、プロセス間のデータ受け渡し、テスト用ファイルの作成など、寿命の短いファイル・ディレクトリが必要となる場面がある。本機能は安全で衝突のない一時パスの生成と、do ブロックによるスコープベースの自動クリーンアップを提供する。

**機能の利用シーン**：テストコードでの一時ファイル作成、大量データの一時的なディスク書き出し、外部プロセスとのファイル経由でのデータ交換、一時的な作業ディレクトリの作成など。

**主要な処理内容**：
1. `tempname` によるユニークな一時ファイルパスの生成
2. `mktemp` / `mktempdir` による一時ファイル・ディレクトリの作成
3. `tempdir` による一時ディレクトリのベースパス取得
4. do ブロック構文による自動クリーンアップ（`mktempdir(f)` パターン）

**関連システム・外部連携**：OS の一時ディレクトリ（`TMPDIR` 環境変数、`/tmp` 等）、libuv の `uv_os_tmpdir` を使用。

**権限による制御**：一時ディレクトリへの書き込み権限が必要。`mktemp` で作成されるファイルは現在のプロセスの所有となる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI / REPL | 主画面 | 一時ファイル関数の対話的実行 |

## 機能種別

ファイルシステム操作 / ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| parent | AbstractString | No | 一時ファイルの親ディレクトリ（デフォルト: tempdir()） | ディレクトリが存在し書き込み可能 |
| prefix | AbstractString | No | 一時ファイル名のプレフィックス | - |
| cleanup | Bool | No | プロセス終了時に自動削除するか（デフォルト: true） | - |

### 入力データソース

ユーザーコードから直接引数として渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| path | String | tempname の場合の一時ファイルパス |
| (path, io) | Tuple{String, IOStream} | mktemp の場合のパスとストリーム |
| path | String | mktempdir の場合の一時ディレクトリパス |

### 出力先

ファイルシステム上に一時ファイルまたはディレクトリが作成される。

## 処理フロー

### 処理シーケンス

```
1. ベースディレクトリの決定
   └─ parent 引数 または tempdir() から取得
2. ユニーク名の生成
   └─ ランダム文字列を使ったユニークなファイル名の生成
3. ファイル/ディレクトリの作成
   └─ open(path, "w") または mkdir(path)
4. クリーンアップ登録（cleanup=true の場合）
   └─ atexit フックまたは finalizer でプロセス終了時の削除を登録
5. do ブロック版の場合
   └─ ブロック実行後に rm(path, recursive=true) を自動実行
```

### フローチャート

```mermaid
flowchart TD
    A[一時ファイル要求] --> B{関数種別}
    B -->|tempname| C[ランダム名生成]
    C --> D[パスのみ返却]
    B -->|mktemp| E[ランダム名生成]
    E --> F[ファイル作成 + open]
    F --> G{do ブロック?}
    G -->|Yes| H[ブロック実行]
    H --> I[ファイル削除]
    G -->|No| J[path, io 返却]
    B -->|mktempdir| K[ランダム名生成]
    K --> L[ディレクトリ作成]
    L --> M{do ブロック?}
    M -->|Yes| N[ブロック実行]
    N --> O[ディレクトリ再帰削除]
    M -->|No| P[path 返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | ユニーク名保証 | 一時ファイル名はランダム文字列により衝突を回避する | tempname/mktemp/mktempdir |
| BR-44-02 | do ブロッククリーンアップ | do ブロック版は例外発生時もクリーンアップを実行する | mktemp(f)/mktempdir(f) |
| BR-44-03 | cleanup フラグ | cleanup=true（デフォルト）ではプロセス終了時に自動削除 | 全一時ファイル関数 |
| BR-44-04 | tempdir のフォールバック | TMPDIR 環境変数が未設定の場合、OS デフォルトの一時ディレクトリを使用 | tempdir() |

### 計算ロジック

一時ファイル名の生成にはランダム文字列（Base62 等のエンコーディング）を使用し、衝突確率を十分に低く抑える。

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

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IOError | SystemError | 一時ディレクトリに書き込み権限がない | TMPDIR 環境変数で別の場所を指定 |
| IOError | SystemError | ディスク容量不足 | ディスク空き容量の確保 |
| ArgumentError | ArgumentError | 無効な親ディレクトリ指定 | 存在するディレクトリを指定 |

### リトライ仕様

ファイル名の衝突が発生した場合は内部的に別のランダム名で再試行する。

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

do ブロック版の `mktempdir` は finally 節でクリーンアップを保証するため、擬似的なトランザクションセマンティクスを持つ。

## パフォーマンス要件

一時ファイルの作成は通常のファイル作成と同等のパフォーマンス。ランダム名の生成は高速（マイクロ秒オーダー）。

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

- `tempname` はパスの生成のみで実際のファイル作成を行わないため、TOCTOU 競合が存在する。`mktemp` の使用が推奨される
- 一時ファイルのパーミッションはデフォルトで現在のユーザーのみアクセス可能に設定される
- cleanup=false の場合、一時ファイルが残存し、ディスク容量を消費し続ける可能性がある

## 備考

- Julia のテストフレームワークは `mktempdir` を多用してテスト用の隔離環境を作成する
- `tempname` の結果はパスの生成のみであり、ファイルは作成されない点に注意

---

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

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

### 推奨読解順序

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

一時ファイル機能は独自のデータ構造を持たず、パス文字列と IOStream を使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | file.jl | `base/file.jl` | `tempdir` 関数で使用される環境変数（TMPDIR, TMP, TEMP）の参照順序を理解する |

**読解のコツ**: 一時ファイル関連の関数は `base/file.jl` の後半に集約されている。do ブロック版は try-finally パターンで実装されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | file.jl | `base/file.jl` | `tempdir()` - libuv の `uv_os_tmpdir` を呼び出してシステムの一時ディレクトリを取得 |
| 2-2 | file.jl | `base/file.jl` | `tempname()` - ランダム文字列でユニークなパスを生成 |
| 2-3 | file.jl | `base/file.jl` | `mktemp()` - ファイルを作成して (path, io) を返却 |
| 2-4 | file.jl | `base/file.jl` | `mktempdir()` - ディレクトリを作成してパスを返却 |

**主要処理フロー**:
1. `tempdir()` でベースパスを取得
2. `temp_cleanup_later()` でクリーンアップ登録（cleanup=true の場合）
3. do ブロック版では try-finally で `rm(path, recursive=true)` を保証

#### Step 3: クリーンアップ機構を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | file.jl | `base/file.jl` | `temp_cleanup_later` - atexit フックを使ったプロセス終了時の自動削除機構 |

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

```
mktemp(parent)
    ├─ tempdir()  ... デフォルト親ディレクトリ取得
    │      └─ ccall(:uv_os_tmpdir)
    ├─ tempname(parent) ... ユニークパス生成
    │      └─ Random.randstring() ... ランダム文字列
    ├─ open(path, "w") ... ファイル作成
    └─ temp_cleanup_later(path) ... クリーンアップ登録

mktempdir(parent)
    ├─ tempdir()
    ├─ tempname(parent)
    ├─ mkdir(path)
    └─ temp_cleanup_later(path)

mktempdir(f, parent)  [do ブロック版]
    ├─ mktempdir(parent) ... ディレクトリ作成
    ├─ f(path)           ... ユーザー関数実行
    └─ rm(path, recursive=true) ... finally で削除
```

### データフロー図

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

(parent省略)  ──────▶ tempdir() ──▶ uv_os_tmpdir ──▶ ベースパス
ベースパス    ──────▶ tempname() ──▶ randstring   ──▶ ユニークパス
ユニークパス  ──────▶ mktemp()  ──▶ open          ──▶ (path, IOStream)
ユニークパス  ──────▶ mktempdir() ──▶ mkdir        ──▶ ディレクトリパス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| file.jl | `base/file.jl` | ソース | 一時ファイル関数の定義（tempname, mktemp, mktempdir, tempdir） |
| path.jl | `base/path.jl` | ソース | パス操作（joinpath 等でパス結合） |
| iostream.jl | `base/iostream.jl` | ソース | mktemp で返される IOStream の定義 |
