ディレクトリはどのように「特別な種類のファイル」ですか?


23

私はこのUnixチュートリアルを読んでいてこの引用に出会いました...

ここで、ディレクトリは単なる特殊なタイプのファイルであることに注意してください。

...しかし、説明や詳細は提供されません。ディレクトリは実際には単なるファイルですか?


回答:


19

* nixスタイル(およびその他)のオペレーティングシステムの多くのエンティティは、ファイルシステムに格納されたバイトシーケンスである必要はありませんが、ファイルと見なされるか、ファイルのような側面を定義します。正確なディレクトリの実装方法はファイルシステムの種類によって異なりますが、一般的にリストとして考慮されるのは格納されたバイトのシーケンスであるため、その意味ではそれほど特別ではありません。

* nixコンテキストで「ファイル」が何であるかを定義する1つの方法は、ファイル記述子が関連付けられているものであることです。ウィキペディアの記事によると、ファイル記述子

パイプやネットワーク接続など、ファイルまたはその他の入出力リソースにアクセスするために使用される抽象的なインジケータです...

言い換えれば、それらは、一連のバイトの読み取り/書き込みが可能なさまざまな種類のリソースを指しますが、そのシーケンスのソース/宛先は指定されていません。言い換えると、リソースの「場所」は何でもかまいません。それを定義するのは、それが情報の導管であるということです。これは、Unixで「すべてがファイルである」と時々言われる理由の一部です。それを完全に文字通りに受け取るべきではありませんが、真剣に検討する価値があります。ディレクトリの場合、この情報はディレクトリ内の内容に関係し、下位の実装レベルでは、ファイルシステム内でそれを見つける方法に関係します。

ネイティブCコードでは、見かけ上ファイル記述子に関連付けられていないため、ディレクトリはこの意味で特別です。POSIX APIは、特殊なタイプのストリームハンドルを使用しDIR*ます。ただし、実際には、このタイプには取得可能な基礎となる記述子があります。記述子はカーネルによって管理され、それらへのアクセスには常にシステムコールが関係するため、記述子のもう1つの側面は、OSカーネルによって制御されるコンジットであることです。これらは、通常は標準入力ストリームの記述子である0で始まる一意の(プロセスごとの)番号を持ってい ます。


2
POSIX.1-2008は、システムコール(の束を加えopenatfstatat使用ファイル記述子がディレクトリを参照して、など)。
zwol

2
さらに興味深いことに、fsync()読み取り専用(!)ディレクトリfd を使用できます。明確な効果があります(具体的には、特定のディレクトリでのファイル作成/名前変更/削除を同期します。一時ファイルに保存し、元の「イディオム」に名前を変更します)。
ケビン

13

Unixのやり方:すべてはファイルです。

ディレクトリは、(多くの)種類の特殊ファイルです。データは含まれていません。代わりに、ディレクトリ内に含まれるすべてのファイルへのポインターが含まれます。

他の種類の特殊ファイル:

  • リンク
  • ソケット
  • デバイス

しかし、それらは「ファイル」と見なされるため、lsそれらを変更して名前を変更し、移動し、特殊ファイルのタイプに応じてデータを送受信できます。


1
そして、これはディレクトリであるという理由だけで別のことをする必要がないので、生活がずっと楽になります。これは、プログラムの作成とコマンドライン(またはGUI)からの操作に適用されます。
gbarry

1
ディレクトリにはデータが含まれています。ディレクトリに含まれるファイルを記述するデータです。ディレクトリにアクセスして(おそらく標準のオープンコールではないかもしれませんが)自分でそのデータを読み取ることは完全に可能ですが、(Bruce Edigerが答えで指摘しているように)データは形式を知らない限りあまり使用されません。
-jamesqf

11

私の答えは単なる思い出ですが、199xのビンテージUnixでは、ディレクトリがファイルであり、ディスク上のiノードのどこかに「ディレクトリ」とマークされていました。

次のようなディレクトリを開いopen(".", O_RDONLY)て、使用可能なファイル記述子を取得できます。ざっと目を通し/usr/include、正しいC構造体定義を見つけた場合は、内容を解析できます。SunOS 4.1.xシステム、SGIのEFSファイルシステム、およびファイルシステム(おそらくBSD4.2 FFS)用のDECのMips-CPUワークステーションでこれを行ったことを知っています。

それは悪い経験でした。ディレクトリが厳密なファイルでなくなったとしても、仮想ファイルシステム層で標準化することは移植性にとって良いことです。VFSレイヤーを使用すると、ReiserFSやNFSなど、ディレクトリがファイルではないファイルシステムを試すことができます。



1
現在でも、ディレクトリを開いて、いくつかのUnixの亜種でファイルとして読み取ることができます。たとえば、FreeBSD 10.1でも可能です。(缶≠する必要があります)
ジル「SO-悪であるのをやめる」

@Gilles ddによってコピーされたディレクトリが本質的にに相当する場合、それは非常に論理的だと思いますがcp --link dir1/* dir2、その使いやすさについてはわかりません。
ペテルはモニカを

3

ディレクトリは、そのモードに「d」があるという点で特別であり、ファイルシステムに、その内容を、単にバイトのシーケンスである通常のファイルではなく、ディレクトリ内に含まれる他のファイルのリストとして解釈する必要があることを伝えますアプリケーションによって読み取られます。それだけです。


すべてのファイルシステムで事態はそれほど単純ではありません-たとえば、AppleのHFS +には、すべてのパス名を含む大きなB +ツリーが1つだけあります(正確に覚えていれば)おそらく、引用されたチュートリアルの著者が考えていたものです。
zwol

2

LinuxシステムはユニバーサルI / Oモデルを採用しているため、ディレクトリはファイルです。モデルでは、システム内のすべてがファイルであり、同じシステムコールとさまざまなコマンドでアクセスできます。

これらのiノードにはファイルタイプのマークがあり、ファイル名と他のiノードへのリンクのテーブルであるという特別な構造があるため、これらは特別なタイプです。これらのファイル名とリンクのペア(「ハードリンク」とも呼ばれる)は、ディレクトリのiノードにあり、ディレクトリの「内部」にあるファイルを列挙します。

ディレクトリはファイルを整理するためのものです。ファイルがディレクトリから別のディレクトリに「移動」されると、ファイル自体はディスク内で再配置されません。1つのディレクトリiノードのエントリが削除され、別のディレクトリiノードに書き込まれるだけです。


-3

受け入れられた答えは完全に正しいわけではありません。POSIXシステムでは、「Inodes」はファイルとディレクトリを指します。ファイル記述子はプロセスにのみ固有であり、システム全体には固有ではありません。ただし、iノードは一意ですが、複数のiノードが単一のファイルを指すことができます。受け入れられた回答についてコメントしたはずですが、担当者の制限のためにできませんでした。


2
いいえ、1つのiノードだけが同じファイルを指すことができます。同じiノードは複数のディレクトリ(または複数の名前)に同時に存在できます。簡単なチェック:ls -l >test.txt;ln -vf test.txt test2.txt;ls -li test.txt test2.txt。したがって、ハードリンクのiノード番号は同じであることがわかります。
ペテルは、モニカを

@peterhファイル記述子はプロセスにのみ一意です。説明できますか?
アラミン

1
@ Md.AlaminMahamudプロセスがfork()s である場合、その子プロセスはO_CLOEXEC、元のプロセスが持っていたファイル記述子エンティティとまったく同じファイル記述子エンティティを持つことになります(特別な状況、つまりフラグを除く)。別の例:apache子プロセスはlisten()同じソケットファイル記述子を使用しています。しかし、この答えはファイル記述子に関するものではありません。ファイル記述子はカーネル内部のデータ構造であり、カーネルメモリにのみ存在します。この(false)答えは、ディレクトリエントリとiノードに関するもので、これらはディスク上のエンティティです(つまり、ハードドライブ上の物理バイトです)。
ペテルは、モニカを

1
@ Md.AlaminMahamudさて、今はよくわかりません。たとえば、fork()発生してから子プロセスがseek()sまたはclose()sになった場合、親のファイル記述子には影響しません。だから私は今、ファイル記述子は部分的にプロセスプライベート構造にすぎないと考えています。しかし、この質問は彼らに関するものではありません。この質問はdirents / inodesに関するものであり、この質問に対する完全に間違った答えについてコメントしています。
ペテルは、モニカを
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.