私はこのUnixチュートリアルを読んでいて、この引用に出会いました...
ここで、ディレクトリは単なる特殊なタイプのファイルであることに注意してください。
...しかし、説明や詳細は提供されません。ディレクトリは実際には単なるファイルですか?
私はこのUnixチュートリアルを読んでいて、この引用に出会いました...
ここで、ディレクトリは単なる特殊なタイプのファイルであることに注意してください。
...しかし、説明や詳細は提供されません。ディレクトリは実際には単なるファイルですか?
回答:
* nixスタイル(およびその他)のオペレーティングシステムの多くのエンティティは、ファイルシステムに格納されたバイトシーケンスである必要はありませんが、ファイルと見なされるか、ファイルのような側面を定義します。正確なディレクトリの実装方法はファイルシステムの種類によって異なりますが、一般的にリストとして考慮されるのは格納されたバイトのシーケンスであるため、その意味ではそれほど特別ではありません。
* nixコンテキストで「ファイル」が何であるかを定義する1つの方法は、ファイル記述子が関連付けられているものであることです。ウィキペディアの記事によると、ファイル記述子
パイプやネットワーク接続など、ファイルまたはその他の入出力リソースにアクセスするために使用される抽象的なインジケータです...
言い換えれば、それらは、一連のバイトの読み取り/書き込みが可能なさまざまな種類のリソースを指しますが、そのシーケンスのソース/宛先は指定されていません。言い換えると、リソースの「場所」は何でもかまいません。それを定義するのは、それが情報の導管であるということです。これは、Unixで「すべてがファイルである」と時々言われる理由の一部です。それを完全に文字通りに受け取るべきではありませんが、真剣に検討する価値があります。ディレクトリの場合、この情報はディレクトリ内の内容に関係し、下位の実装レベルでは、ファイルシステム内でそれを見つける方法に関係します。
ネイティブCコードでは、見かけ上ファイル記述子に関連付けられていないため、ディレクトリはこの意味で特別です。POSIX APIは、特殊なタイプのストリームハンドルを使用しDIR*
ます。ただし、実際には、このタイプには取得可能な基礎となる記述子があります。記述子はカーネルによって管理され、それらへのアクセスには常にシステムコールが関係するため、記述子のもう1つの側面は、OSカーネルによって制御されるコンジットであることです。これらは、通常は標準入力ストリームの記述子である0で始まる一意の(プロセスごとの)番号を持ってい ます。
openat
、fstatat
使用ファイル記述子がディレクトリを参照して、など)。
fsync()
読み取り専用(!)ディレクトリfd を使用できます。明確な効果があります(具体的には、特定のディレクトリでのファイル作成/名前変更/削除を同期します。一時ファイルに保存し、元の「イディオム」に名前を変更します)。
Unixのやり方:すべてはファイルです。
ディレクトリは、(多くの)種類の特殊ファイルです。データは含まれていません。代わりに、ディレクトリ内に含まれるすべてのファイルへのポインターが含まれます。
他の種類の特殊ファイル:
しかし、それらは「ファイル」と見なされるため、ls
それらを変更して名前を変更し、移動し、特殊ファイルのタイプに応じてデータを送受信できます。
私の答えは単なる思い出ですが、199xのビンテージUnixでは、ディレクトリがファイルであり、ディスク上のiノードのどこかに「ディレクトリ」とマークされていました。
次のようなディレクトリを開いopen(".", O_RDONLY)
て、使用可能なファイル記述子を取得できます。ざっと目を通し/usr/include
、正しいC構造体定義を見つけた場合は、内容を解析できます。SunOS 4.1.xシステム、SGIのEFSファイルシステム、およびファイルシステム(おそらくBSD4.2 FFS)用のDECのMips-CPUワークステーションでこれを行ったことを知っています。
それは悪い経験でした。ディレクトリが厳密なファイルでなくなったとしても、仮想ファイルシステム層で標準化することは移植性にとって良いことです。VFSレイヤーを使用すると、ReiserFSやNFSなど、ディレクトリがファイルではないファイルシステムを試すことができます。
cp --link dir1/* dir2
、その使いやすさについてはわかりません。
LinuxシステムはユニバーサルI / Oモデルを採用しているため、ディレクトリはファイルです。モデルでは、システム内のすべてがファイルであり、同じシステムコールとさまざまなコマンドでアクセスできます。
これらのiノードにはファイルタイプのマークがあり、ファイル名と他のiノードへのリンクのテーブルであるという特別な構造があるため、これらは特別なタイプです。これらのファイル名とリンクのペア(「ハードリンク」とも呼ばれる)は、ディレクトリのiノードにあり、ディレクトリの「内部」にあるファイルを列挙します。
ディレクトリはファイルを整理するためのものです。ファイルがディレクトリから別のディレクトリに「移動」されると、ファイル自体はディスク内で再配置されません。1つのディレクトリiノードのエントリが削除され、別のディレクトリiノードに書き込まれるだけです。
受け入れられた答えは完全に正しいわけではありません。POSIXシステムでは、「Inodes」はファイルとディレクトリを指します。ファイル記述子はプロセスにのみ固有であり、システム全体には固有ではありません。ただし、iノードは一意ですが、複数のiノードが単一のファイルを指すことができます。受け入れられた回答についてコメントしたはずですが、担当者の制限のためにできませんでした。
ls -l >test.txt;ln -vf test.txt test2.txt;ls -li test.txt test2.txt
。したがって、ハードリンクのiノード番号は同じであることがわかります。
fork()
s である場合、その子プロセスはO_CLOEXEC
、元のプロセスが持っていたファイル記述子エンティティとまったく同じファイル記述子エンティティを持つことになります(特別な状況、つまりフラグを除く)。別の例:apache子プロセスはlisten()
同じソケットファイル記述子を使用しています。しかし、この答えはファイル記述子に関するものではありません。ファイル記述子はカーネル内部のデータ構造であり、カーネルメモリにのみ存在します。この(false)答えは、ディレクトリエントリとiノードに関するもので、これらはディスク上のエンティティです(つまり、ハードドライブ上の物理バイトです)。
fork()
発生してから子プロセスがseek()
sまたはclose()
sになった場合、親のファイル記述子には影響しません。だから私は今、ファイル記述子は部分的にプロセスプライベート構造にすぎないと考えています。しかし、この質問は彼らに関するものではありません。この質問はdirents / inodesに関するものであり、この質問に対する完全に間違った答えについてコメントしています。