Linux ファイル記述子、ファイルポインタ、および inode の詳細

Linux ファイル記述子、ファイルポインタ、および inode の詳細

Linux - ファイル記述子、ファイルポインタ、インデックスノード

1. Linux - ファイル記述子

1. ファイル記述子 Fd

プロセスがファイルを開いたり、新しいファイルを作成したりすると、カーネルは開かれたファイルを指すファイル記述子 (負でない整数) を返します。I/O 操作を実行するすべてのシステム コール (読み取り、書き込み) は、ファイル記述子を通過します。

ファイル記述子は、プロセス ファイル記述テーブルのインデックスとして理解できます。また、ファイル記述テーブルが配列と見なされる場合は、ファイル記述子を配列の添え字として見なすことができます。 I/O 操作が必要な場合、fd がパラメータとして渡されます。まず、プロセス ファイル記述子テーブルから fd に対応するエントリが検索され、対応するオープン ファイルのハンドルが取り出されます。ファイル ハンドルが指している値に従って、ファイルが指している inode がシステム fd テーブル内で検索され、ファイルの実際の位置が特定されて I/O 操作が実行されます。

特徴:

  • 各ファイル記述子は開いているファイルに対応します。
  • 異なるファイル記述子が同じファイルを参照する場合があります。
  • 同じファイルを異なるプロセスで開くことも、同じプロセスで複数回開くこともできます。

関連する 3 つの表は次のとおりです。

プロセスレベルのファイル記述子テーブル

構造体task_struct {
  //...
  
    struct files_struct *files //プロセスレベルのファイル記述子テーブル//...
    
};

2. システムレベルのファイル記述子テーブル

カーネルは、システム内のすべてのオープン ファイルの打開文件表を管理します。テーブル内の各項目は、打開文件句柄と呼ばれます。オープン ファイル ハンドルは、オープン ファイルのすべての情報を記述します。

  • 現在のファイル オフセット (read() および write() の呼び出し時に更新されるか、lseek() で直接変更されます)
  • ファイルを開くときに使用されるステータス フラグ (つまり、open() の flags パラメータ)
  • ファイル アクセス モード (読み取り専用モード、書き込み専用モード、open() 呼び出し時に設定される読み取り/書き込みモードなど)
  • 信号ドライバ関連の設定
  • ファイルのi-nodeオブジェクトへの参照
  • ファイルの種類(通常のファイル、ソケット、FIFO など)とアクセス権限
  • ファイルが保持するロックのリストへのポインタ
  • ファイルのさまざまなプロパティ(ファイルサイズ、さまざまな種類の操作に関連付けられたタイムスタンプなど)

3. ファイルシステムのinodeテーブル

各ファイル システムは、そこに保存されているすべてのファイルの inode テーブルを保持します。

ファイル記述子テーブル、オープン ファイル テーブル、および inode テーブルの関係:

プロセス A のファイル記述子 1 と 20 は、open() やその他の関数を複数回呼び出すことによって同じファイルが開かれるため、同じ開いているファイル ハンドルを指します。

プロセス A のファイル記述子 2 とプロセス B のファイル記述子 2 が同じオープン ファイル ハンドルを指している理由は、fork() の呼び出しによるものと考えられます。子プロセスは親プロセスのオープン ファイル記述子テーブルを継承します。つまり、子プロセスは親プロセスのオープン ファイルを継承します。 ; または、プロセスが Unix ドメイン ソケットを介して開いているファイル記述子を別のプロセスに渡すか、または異なるプロセスが独立して open 関数を呼び出して同じファイルを開き、ファイル記述子が他のプロセスによって開かれたファイル記述子と同じに割り当てられます。

プロセス A の記述子 0 とプロセス B の記述子 3 は、異なるオープン ファイル ハンドルを指していますが、これらのハンドルはすべて i-node テーブル内の同じエントリ、つまり同じファイルを指しています。これは、各プロセスが同じファイルに対して open() 呼び出しを開始したために発生します。同じプロセスが同じファイルを 2 回開いた場合にも同様の状況が発生します。

2. ファイルポインタ *FILE

C 言語では、I/O ハンドルとしてファイル記述子の代わりにファイル ポインタを使用します。「ファイル ポインタ」は、プロセス ユーザー領域内の FILE 構造と呼ばれるデータ構造を指します。ファイルポインタを介してファイルを操作する場合には、C言語のstdio.hで提供されているファイルAPI(fopen()、fread()など)を呼び出す必要があります。

ファイル記述子は POSIX システム コールで直接表示され、ファイル ポインターはそれらの上にある C 言語ラッパーです。

int open(const char *path, int access, int mode)  
FILE *fopen(char *ファイル名, char *モード)

ファイル ポインターへのファイル パス: filepath --fopen()-->FILE*;
ファイル記述子へのファイル パス: filepath--open()--fd;
ファイル記述子からファイル ポインターへ: fd--fdopen()-->FILE*;
ファイル記述子へのファイルポインター: FILE*--fileno()--->fd;

3. インデックスノードの Inode

インデックス ノードは、Unix 系システムのファイル システム内のオブジェクトのメタデータを格納するデータ構造です。

inode には主に以下のデータが格納されます。

  • iノード番号
  • ファイルサイズ
  • 占有ブロック数とブロックサイズ
  • ファイルの種類(通常のファイル、ディレクトリ、パイプなど)
  • ファイルが保存されているデバイス番号
  • リンク数
  • 読み取り、書き込み、実行権限
  • 所有者のユーザーIDとグループID
  • ファイルが最後にアクセスされ、データが最後に変更された時刻
  • inodeが最後に変更された時刻

statコマンドを使用してメタデータを表示し、df -i コマンドを使用して、inode の合計数と各ハードディスク パーティションに使用されている inode の数を表示できます。ファイル名以外のすべての情報は、inode に保存されます。

i ノードもハードディスクの容量を消費するため、ハードディスクをフォーマットすると、オペレーティング システムによってハードディスクが自動的に 2 つの領域に分割されます。 1 つはファイル データを格納するデータ領域であり、もう 1 つは inode に含まれる情報を格納する inode 領域 (inode テーブル) です。

各 inode ノードのサイズは通常128字節または256字節です。 inode ノードの合計数はフォーマット時に指定され、通常は 1KB または 2KB ごとに 1 つの inode が設定されます。 1GB のハードディスクで、各 inode ノードのサイズが 128 バイトで、1KB ごとに 1 つの inode が設定されると仮定すると、inode テーブルのサイズは 128MB に達し、ハードディスク全体の 12.8% を占めることになります。

各ファイルには inode があるため、inode が使い果たされていてもハードディスクがいっぱいになっていない可能性があります。 Linux システムでは、ファイル名ではなく i ノードを使用してファイルを識別します。

表面的には、ユーザーはファイル名でファイルを開きます。実際、システム内のこのプロセスは 3 つのステップに分かれています。まず、システムはファイル名に対応する inode 番号を見つけます。次に、inode 番号を通じて inode 情報を取得します。最後に、inode 情報に基づいて、ファイル データが配置されているブロックを見つけ、データを読み取ります。

ディレクトリ ファイルは、一連のディレクトリ エントリで構成されるデータ構造であり、各ディレクトリ エントリにはファイル名と inode 番号の 2 つの部分が含まれます。

1. Inodeの特別な役割

  • 場合によっては、ファイル名に通常は削除できない特殊文字が含まれていることがあります。このとき、inode ノードを直接削除すると、ファイルを削除できます。
  • ファイルを移動または名前変更すると、ファイル名のみが変更され、inode 番号には影響しません。
  • ファイルを開いた後、システムはそのファイルを inode 番号で識別し、ファイル名は考慮しなくなります。したがって、一般的に、システムは inode 番号からファイル名を認識することはできません。

ポイント 3 では、ソフトウェアの更新が簡単になり、ソフトウェアをシャットダウンしたり再起動したりすることなく更新できます。システムは実行中のファイルをファイル名ではなく、inode 番号で識別するためです。更新すると、ファイルの新しいバージョンによって同じファイル名を持つ新しい inode が生成されますが、実行中のファイルには影響しません。次回ソフトウェアを実行すると、ファイル名は自動的に新しいバージョンのファイルを指し、古いバージョンのファイルの inode はリサイクルされます。

4. 拡大

1. ディスク構造

ファイルはハードディスクに保存され、ハードディスクの最小の保存単位は「セクター」と呼ばれます。各セクターには 512 バイト (0.5 KB に相当) が格納されます。

オペレーティング システムがハード ディスクを読み取るとき、セクターごとに読み取るのではなく (これは非常に非効率的です)、一度に複数のセクターを連続して読み取ります。つまり、一度に 1 つの「ブロック」を読み取ります。複数のセクターで構成されるこの「ブロック」は、ファイル アクセスの最小単位です。最も一般的な「ブロック」サイズは 4KB です。つまり、8 つの連続したセクターがブロックを形成します。

上記から、(柱面號,盤面號,扇區號)を使用して、任意の「ディスクブロック」を見つけることができます。外部メモリ内のファイルデータが保存されているブロック番号(論理アドレス)についてよく言及します。このブロック番号は、(シリンダ番号、ディスク面番号、セクター番号)のアドレス形式に変換できます。

このアドレスから「ブロック」は次のように読み取ることができます。

①「シリンダ番号」に従って磁気アームを動かし、磁気ヘッドが指定のシリンダ(トラックとも言う)を指すようにする

②指定されたディスク面に対応するヘッドを作動させる。

③ ディスクが回転すると、指定されたセクタがヘッドの下を通過し、指定されたセクタの読み取り/書き込みが完了します。

Linux ファイル ディスクリプタ、ファイル ポインタ、インデックス ノードの詳細に関するこの記事はこれで終わりです。Linux ファイル ディスクリプタ、ファイル ポインタ、インデックス ノードに関するより詳しい情報については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Linux インデックスノード inode の詳細な説明
  • Linux デバイスに空き容量がありません inode の満杯により 500 エラーが発生します
  • Linux ネットワーク設定の詳細
  • MyCat を使用して Linux で MySQL マスター/スレーブの読み取り/書き込み分離を実装する方法
  • Unix/Linuxフォークの隠れたオーバーヘッド
  • Linux での UDP について学ぶ
  • Linux スワップ パーティション (詳細説明)
  • Linux での C++ ネットワーク プログラミング、epoll テクノロジ、Windows での IOCP モデル
  • Linux サーバーは最大いくつのポートを開くことができますか?

<<:  div を下から上にスライドさせる CSS3 の例

>>:  フォーム内のどの隠し属性をフォームとともに送信できるか

推薦する

HTML iframe で親ページと子ページ間の双方向メッセージングを実装する例

ある日、リーダーはメイン ページに iframe を埋め込み、親ページと子ページ間で双方向にメッセー...

仮想スクロールを簡単に実装するためのVueサンプルコード

目次序文ローリング原理成し遂げるソースコード参照する序文モバイル Web ページの日常的な開発では、...

Linuxでテキスト比較を実現するコツを教えます

序文コードを書く過程で、必然的にコードに何らかの変更を加えることになります。しかし、変更を加えるとき...

CSS を使用してデータ ホットスポット効果を実現する方法

効果は以下のとおりです。 分析する1. ここでは、点を囲む 3 つの円がズームアニメーションを実行し...

HTML チュートリアル: title 属性と alt 属性

XHTML は CSS レイアウトの基礎です。jb51.net は常に XHTML 知識の習得を重視...

CSS で隠し要素を実現する 7 つの興味深い方法

序文非表示要素の 3 つの属性である表示、可視性、不透明度の類似点と相違点は、フロントエンドの就職面...

MySQL 30軍事ルールの詳細な説明

1. 基本仕様(1)InnoDBストレージエンジンを使用する必要があります。解釈:トランザクション、...

UbuntuでOpenCVをコンパイルしてインストールする方法

opencv2 の簡単なインストール: conda インストール --channel https:/...

CSS における重要なカスケード概念の詳細な説明

最近、プロジェクトの過程で問題に遭遇しました。メニューバーを常に上部に表示し、後続の要素をその下に表...

Docker コンテナのネットワーク設定によく使われるコマンドの詳しい説明

基本的なネットワーク構成Docker はイメージに基づいて複数のコンテナを「開く」ことができ、各コン...

JS と Nodejs におけるイベント駆動型開発についての簡単な説明

目次イベント駆動型とパブリッシュ・サブスクライブ型ブラウザの JavaScript ではイベント駆動...

Linuxでmore、less、catコマンドを使用してファイルの内容を表示します

Linux では、cat、more、less の各コマンドを使用してファイルの内容を表示できます。c...

MySQL Routerのインストールと展開

目次01 MySQLルーターの紹介MySQL Router とは何ですか? 02 MySQLルータの...

Reactのコンテキストとプロパティの説明

目次1. 文脈1. 使用シナリオ2. 使用手順3. 結論2. 小道具の詳細1. 子供の財産2. 小道...

フレームセットの共通プロパティ(フレームとウィンドウの分割)

フレームとは、Web ページ画面を複数のフレームに分割したもの(複数の Web ページという形で表示...