https://qiita.com/toshihirock/items/78286fccf07dbe6df38f
More than 5 years have passed since last update.
ファイルディスクリプタについて分かっているような分かっていないような感じだったのRubyでコードを書きつつ、理解したときのメモ
以下より引用
ファイルディスクリプタとは、プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子。0から順番に整数の値が割り当てられる。OSによってはファイルディスクリプタにバッファ管理機能なども含めた「ファイルハンドル」と呼ばれる管理体系が存在する。
ファイルディスクリプタには、識別子とともにファイル名、ファイルサイズ、プログラムが操作中のファイル内の位置、ファイル作成、更新日時などの情報が含まれており、OSは識別子によってどのファイルを操作するかを判断する。
通常、0:標準入力(stdin)、1:標準出力(stdout)、2:標準エラー出力(stderr)の3つはOS(シェル)が最初に用意するため、プログラムがファイルをオープンすると「3」から順番にディスクリプタが割り当てられる。
分かったようなわからない部分もあるような。 実際にコードなどを書いて挙動を確認します。
RubyでIOクラスのメソッドではファイルディスクリプタの番号をfilenoメソッドで取得できるので、上記の最後の部分に書いてある事項について確認してみます。
descriptor.rb
puts $stdin.fileno # 0
puts $stdout.fileno # 1
puts $stderr.fileno # 2
確かに標準入力、標準出力、標準エラー出力にそれぞれファイルディスクリプタが上記数字の通り、割り当たっていることが分かりました。
今度は既存ファイルをread権限で読み込み、そのファイルディスクリプタの番号を取得してみます。
read.rb
file = File.open('/etc/hosts', 'r')
puts file.fileno # 7
puts file.readline # 1行目を表示
puts file.readline # 2行目を表示
file.close
プロセス(今回はRubyプログラム)から直接ファイルへのIOは出来ないため、ファイルの読み込みなどは内部的にはカーネルを介して行っています。
上記プログラムの場合には以下をやっていることとなります。