ディレクトリ

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

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

概要

ディレクトリ構造の例。この図では、ルートはMFD (Master File Directory) として記述されている。

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

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

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

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

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

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

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

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

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

API

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

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

POSIX

  • mkdir()
  • rmdir()
  • opendir()
  • fdopendir()
  • readdir()
  • readdir_r()
  • rewinddir()
  • closedir()

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

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

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

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

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

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

Windows API

  • CreateDirectory()
  • RemoveDirectory()
  • FindFirstFile()
  • FindNextFile()
  • FindClose()

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

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

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

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

符号位置

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

記号 Unicode JIS X 0213 文字参照 名称
📁 U+1F4C1 - 📁
📁
FILE FOLDERファイル・フォルダー
📂 U+1F4C2 - 📂
📂
OPEN FILE FOLDERオープン・ファイル・フォルダー
🖿 U+1F5BF - 🖿
🖿
BLACK FOLDERブラック・フォルダー
🗀 U+1F5C0 - 🗀
🗀
FOLDERフォルダー
🗁 U+1F5C1 - 🗁
🗁
OPEN FOLDERオープン・フォルダー

脚注

注釈

  1. ^ 正確には「特殊なファイルとして実装されることが多い」。
  2. ^ Microsoft Windows Vista以前の日本語版では「フォルダ」と表記されていたが、2008年以降のマイクロソフトの外来語表記ルール変更により、Microsoft Windows 7以降の日本語版では長音符を付けた「フォルダー」と表記されるようになった。
  3. ^ フロッピーの場合で明らかなように[要説明]、ディスク単位ではない。なお、物理的なディスク上の複数のパーティションなどに対し論理ドライブをそれぞれ割り当てることもできる。
  4. ^ 実際には後述する絶対パスの最大長などによる制限がある。
  5. ^ ASCII の 0x5C の文字が表示されているはずだが、実際にどのように表示されるかは言語やフォントなどの環境に依存する。MS-DOS/Windowsのセパレータの 0x5C というコードは ASCII ではバックスラッシュだが、ISO 646 であえて統一化されず自由領域として残されたコードであったため、JIS X 0201 では0x5Cが半角円記号(¥)として使われた。Shift_JISの派生版であるMacJapaneseでは0x5Cが円記号として使われるが、別途バックスラッシュが0x80に割り当てられた。さらにUnicodeでは円記号がU+00A5として別途規定された。このため、文字コード変換のアルゴリズムによって変換結果が左右されてしまい、また可逆変換にはならないことがある。
  6. ^ MS-DOSにおけるカレントディレクトリに関しては、元々シングルタスクが前提のCP/M風の設計だったところに、無理やりUnix風のシステムをツギハギしたものになっていて変なこと[要説明]になっており、ディレクトリだけでなく「カレントドライブ」というものもあってややこしいため、敢えて無視する。
  7. ^ nobodyなどの特殊なアカウントの場合は違うこともある。
  8. ^ Unixのlsコマンドや、シェルでの * による展開では、通常はソートされるためわからないが、lsの -f オプションなどで実際の順番を確認できる。
  9. ^ MS-DOSをバイパスする形で実現しているため、LFNVFAT)導入時にはトラブルになった。
  10. ^ SHGetSpecialFolderPath()[9]およびSHGetFolderPath()[10]の後継であり、Microsoft Windows Vista以降で実装されている。

出典

  1. ^ Raymond Chen (2011年2月16日). “What is the difference between a directory and a folder?”. 2021年2月12日閲覧。
  2. ^ ASCII.jp:Windowsのパス区切り文字は、なぜ逆スラッシュになったのか?
  3. ^ 発行者 塚本慶一郎『標準MS-DOSハンドブック』株式会社アスキー、1984年7月10日、107-110頁。ISBN 4-87148-742-3 
  4. ^ fdopendir, opendir — open directory associated with file descriptor | The Open Group Base Specifications Issue 8 / IEEE Std 1003.1-2024
  5. ^ readdir, readdir_r — read a directory | The Open Group Base Specifications Issue 8 / IEEE Std 1003.1-2024
  6. ^ Listing the Files in a Directory - Win32 apps | Microsoft Learn
  7. ^ SHCreateDirectoryExW function (shlobj_core.h) - Win32 apps | Microsoft Learn
  8. ^ SHGetKnownFolderPath function (shlobj_core.h) - Win32 apps | Microsoft Learn
  9. ^ SHGetSpecialFolderPathW function (shlobj_core.h) - Win32 apps | Microsoft Learn
  10. ^ SHGetFolderPathW function (shlobj_core.h) - Win32 apps | Microsoft Learn

関連項目

外部リンク