ディレクトリ

**ディレクトリ**（）は、コンピュータのファイルシステムにおいて、ファイルをグループ化するための特殊なファイルで、整理・管理などの目的で活用される。ディレクトリの中にも、通常のファイルだけでなく入れ子的にディレクトリを作って、任意の階層を持たせて管理できることがほとんどである。

ファイルの入れ物（容器）などとも表現され、GUIでは文具の**フォルダー**（）のようなメタファーで表現されることが多い。このフォルダーはディレクトリと内部的に同じである場合もあれば、そうでない場合もある。

## 概要

UnixやDOS、バージョン3.1以前のWindowsなどでは「ディレクトリ」と呼び、Mac OSやiOSやAndroidなどでは「フォルダ」と呼んでいる。Windows 95以降のエクスプローラーでは仮想的な階層構造であるシェル名前空間が導入され、GUI上はフォルダ（フォルダー）と呼称するようになったが、ディレクトリと完全に同義ではない。例えば、コントロールパネルやネットワーク、圧縮フォルダーなどは、ファイルシステム上のディレクトリとは異なる仮想的なフォルダーである。GoogleドライブやOneDriveのようなオンラインストレージサービスにもフォルダ（フォルダー）の概念がある。

Unixなどでは唯一の最上位の根幹（ルート、ルートディレクトリ）があり、ストレージやボリューム（パーティションなど）の内容は、任意の枝（マウントポイント）にマウント（接ぎ木）される、というツリー（木）モデルとなっている。それに対し、DOSおよびWindowsでは、最上位は「ドライブ」という単位であり、各ドライブに対してそれぞれのメディアのルートディレクトリがあって、それぞれのツリーがある、という（数学では「林」あるいは「森」と呼んで、「木」と区別することがある）ようなモデルとなっている。

ディレクトリにより任意の深さの階層を構成することが可能なシステムでは、システムコール上のファイルの指定を、カレントディレクトリ（後述）の移動とファイルの指定のようにして別々に行わなければならないシステムもあるが、Unixなど多くのように「ディレクトリ名/ディレクトリ名/ディレクトリ名/ファイル名」のようにセパレータ（分離符、区切り文字）で分離する表現により一度に行えるものもある。セパレータは、Unixでは '`/`'（スラッシュ）、DOSやWindowsでは '`&#x5C;`'（コードが 0x5C の文字）である。なお、DOSのセパレータは、内部的にはスラッシュへの切り替えにも対応していた。Windowsでは、多くの場面でセパレータとして0x5Cの代わりにスラッシュも使うことができるが、APIによってはスラッシュに対応しておらず、0x5Cのみを受け付けるものもある。

（セパレータが使えるシステムでは）先頭をセパレータで始めるなどの方法により、ルートディレクトリからの絶対的な表現で指定したパスを「絶対パス」や「フルパス」と呼ぶ。それに対して、カレントディレクトリ（後述）など、なんらかの任意のディレクトリから相対的に指定することもできる。これを「相対パス」と呼ぶ。例えば`note.txt`や`../2024-04/note.txt`などが相対パスである。相対パスは特に注意深く扱う必要がある。ユーザーから与えられたパスを無害化する処理を施しておかないと、ディレクトリトラバーサルなどの攻撃を許すセキュリティホール（セキュリティ脆弱性）を簡単に生み出してしまう。

Unixなどでは、プロセスの持つ属性として、カレントディレクトリ（あるいはワーキングディレクトリ）がある。そのプロセスが発行するシステムコール中において、相対パスで指定された場合の起点としてなど「デフォルトのディレクトリ」として使われる。子プロセスの起動時には、その時点での親プロセスのカレントディレクトリが引き継がれるか、明示的に指定することができるものもある。原則として子プロセスは親プロセスに影響を与えることができないため、「シェルのカレントディレクトリを変更する」というコマンドは外部コマンドとして実装することができないので、必ずシェルの内部コマンドとして実装される。

Unixにはディレクトリの内容を表示する外部コマンドとして `ls` コマンドがあり、Domain/OSには、相当するコマンドとして `ld`がある。なお、DOSのCOMMAND.COMには、相当する機能を持つ内部コマンド `dir` があり、DISK-BASICには、相当するコマンドとして`files`と`lfiles`がある。

Unixなどでは、ユーザーごとにホームディレクトリが設定されており（passwdファイルなどで）、そのユーザーのログイン後の最初のプロセス（通常はシェル）の初期カレントディレクトリがそれになる。通常、そのユーザーが所有者かつ読み書き可能に設定されており、その下にユーザー個人のファイルを置くことが多い。

Unixをはじめ多くのシステムでは、ディレクトリ中のファイル名（正確には、「ディレクトリエントリ」）の順番をユーザーが編集することはできないが、DOSでは比較的容易に直接ディスクの内容を改変して編集できたため、FDやマイクロデータの「エコロジー」シリーズなど、そのような編集機能を持つファイル管理ソフトもあった。

商用UNIXや、FreeBSDなどいわゆるBSD系のシステムでは、GNU/Linuxにおけるcoreutilsに相当するような基本的なユーティリティ類は全て、カーネルと同じプロジェクトとして維持管理されているいわゆるベースシステムに含まれており、通常は各システムのデフォルトの配置が使用されるため問題が起きることは少ないが、GNU/Linuxでは以前はディストリビューションごとにまちまちであったために面倒な作業などが必要になることがあったため、Filesystem Hierarchy Standard (FHS) により標準化が図られている。

## API
プラットフォームごとにディレクトリを扱うためのシステムコールやAPIが用意されている。代表的なものには大別してPOSIXとWindows APIがあり、C言語互換のインタフェースを持つ関数として提供されている。OSのシェルやシステムコマンドもこれらの上に構築されており、その動作はシステムコールやAPIの仕様の影響を少なからず受けている。

Javaや.NETなどの標準クラスライブラリにおけるディレクトリ操作APIは内部でこれらを使用して実装されている。Pythonのような動的言語のライブラリも同様である。

### POSIX
* `mkdir()`
* `rmdir()`
* `opendir()`
* `fdopendir()`
* `readdir()`
* `readdir_r()`
* `rewinddir()`
* `closedir()`

ディレクトリを作成する場合は、`mkdir()`を使う。

ディレクトリを削除する場合は、`rmdir()`を使うが、中身が空である必要がある。

ディレクトリ内にある項目を列挙する場合は、`opendir()`にディレクトリのパス文字列を渡して生成した`DIR`オブジェクトを使い、`readdir()`で列挙していく。使い終わった`DIR`オブジェクトは`closedir()`で破棄する。

もともと`readdir()`は、呼び出しのたびに上書きされる静的な内部バッファへのポインタを返していたため、スレッドセーフではなかった。`readdir_r()`は引数経由でユーザー提供のバッファに対して値を書き込むことでスレッドセーフ性（再入可能性）を追加した関数だが、呼び出し側によってバッファサイズを指定することができず、ファイル名を保持するのに十分なバッファを確実に割り当てる方法がないという設計欠陥をかかえていた。そのため、IEEE 1003.1-2024 Issue 8では`readdir_r()`は廃止予定（obsolescent）となり、代わりに`readdir()`は（単一のディレクトリストリームに対して異なるスレッドからの同時並行的な呼び出しがない限り）スレッドセーフであることが要求されるようになっている。

`fdopendir()`はファイル記述子に対応したバージョンである。

`seekdir()`や`telldir()`といった拡張 (XSI) をサポートしている実装もある。

### Windows API
* `CreateDirectory()`
* `RemoveDirectory()`
* `FindFirstFile()`
* `FindNextFile()`
* `FindClose()`

ディレクトリを作成する場合は、`CreateDirectory()`を使う。

ディレクトリを削除する場合は、`RemoveDirectory()`を使うが、中身が空である必要がある。

ディレクトリ内にある項目を列挙する場合は、`FindFirstFile()`にディレクトリのパス文字列を渡して生成した`HANDLE`オブジェクトを使い、`FindNextFile()`で列挙していく。使い終わった`HANDLE`オブジェクトは`FindClose()`で破棄する。

他にも、Windowsのバージョンによっては、ディレクトリ階層を一度の呼び出しで作成する`SHCreateDirectoryEx()`、ログインユーザーのホームディレクトリやデスクトップなどのよく使われる特殊なフォルダーのパスを取得する`SHGetKnownFolderPath()`といった上位のシェルAPIもサポートしている。

## 符号位置

GUIで表現されるディレクトリ（フォルダー）のアイコンは、絵文字としてUnicodeに収録されている。なお、U+1F4C1とU+1F4C2の2つはUnicode 6.0で、U+1F5BF、U+1F5C0、U+1F5C1の3つはUnicode 7.0で追加されたものである。

## 脚注
### 注釈

### 出典

## 関連項目
* ファイル (コンピュータ)
* ディレクトリトラバーサル
* Active Directory

## 外部リンク

*のディレクトリ構成
*のディレクトリ構造の一覧（）
*FHSにおけるディレクトリ構成
*第2回　各ディレクトリの役割を知ろう（ルートディレクトリ編）
*第3回　各ディレクトリの役割を知ろう（サブディレクトリ編）
*及びのファイルシステムの構造