[解決済み] RubyのFile.openとf.closeの必要性
質問
多くのプログラミング言語では、ファイルを扱う際の流れはopen-use-closeであることが常識となっています。しかし、rubyのコードでFile.openの呼び出しが一致しないものを何度も見ましたし、さらには という珠玉の知識を発見しました。 を見つけました。
I/Oストリームは、ガベージコレクタによって要求されると自動的に閉じられます。
darkredandyellow
この問題に対するフレンドリーなircのテイク。
[17:12] そうそう、あと、ファイルディスクリプタの数は通常OSによって制限されています。
[17:29] 利用可能なファイルディスクリプタを簡単に使い果たすことができると仮定します。
の前に
ガベージコレクタがクリーンアップする前に、利用可能なファイル記述子を簡単に使い果たすことができると思います。
- 明示的にファイルを閉じる必要があるのか
- もしそうなら、なぜGCは自動終了するのですか?
- そうでないなら、なぜそのようなオプションがあるのでしょうか?
どのように解決するのですか?
<ブロッククオート
Rubyのコードで、マッチしないものを何度も見ました。
File.open
を呼び出す
例を挙げていただけますか?私は、以下のような初心者が書いたコードでしか見たことがありません。 を欠いている ファイルを操作するためのフローは open-use-close" であるという、ほとんどのプログラミング言語における共通の知識を持っていない初心者が書いたコードで見られるだけです。
経験豊富な Rubyist は、ファイルを明示的に閉じるか、より慣用的な方法として、ブロック形式の
File.open
というブロック形式で、自動的にファイルを閉じます。その実装は基本的に次のようなものです。
def File.open(*args, &block)
return open_with_block(*args, &block) if block_given?
open_without_block(*args)
end
def File.open_without_block(*args)
# do whatever ...
end
def File.open_with_block(*args)
yield f = open_without_block(*args)
ensure
f.close
end
スクリプトは特別なケースです。スクリプトは一般に非常に短く実行され、ファイル記述子をほとんど使用しないので、スクリプトが終了したときにオペレーティング システムがいずれにせよそれらを閉じるので、単純に閉じることは意味がありません。
明示的に閉じる必要があるのでしょうか?
はい。
<ブロッククオートもしそうなら、なぜGCは自動終了するのでしょうか?
なぜなら、GCがオブジェクトを収集した後、もうファイルをクローズする方法がないからで、したがって、ファイル記述子をリークすることになります。
ファイルをクローズするのはガベージコレクタではないことに注意してください。ガベージコレクターは、オブジェクトを収集する前に、オブジェクトのファイナライザーをすべて実行するだけです。それは、たまたま
File
クラスはファイルを閉じるファイナライザを定義しています。
そうでない場合、なぜオプションがあるのでしょうか?
無駄なメモリは安価ですが、無駄なファイル記述子はそうではないからです。したがって、ファイル記述子の寿命をメモリのいくつかのチャンクの寿命に結びつけることは意味を持ちません。
あなたは単に いつ ガベージコレクタが実行されるかを予測することはできません。予測することさえできません。 もし が実行されるかどうかを予測することもできません。 で もしメモリ不足にならなければ、ガベージコレクタは決して実行されず、したがってファイナライザは決して実行されず、したがってファイルは決してクローズされません。
関連
-
[解決済み] Rubyのダブルコロン `::` とは何ですか?
-
[解決済み] ファイルの作成日時、変更日時を取得する方法
-
[解決済み] Ruby on Railsで現在の絶対URLを取得するにはどうすればよいですか?
-
[解決済み] gemのインストールで --no-ri --no-rdoc をデフォルトにするには?
-
[解決済み] サーバーを介さずに、ユーザーがダウンロードできるファイルをメモリ上に作成するにはどうすればよいですか?
-
[解決済み] Rubyのattr_accessor, attr_reader, attr_writerを使う理由は?
-
[解決済み】Rubyのdupメソッドとcloneメソッドの違いとは?
-
[解決済み】RubyにあってPythonにないもの、またその逆は何ですか?
-
[解決済み] RubyのFile.openのモードとオプションは何ですか?
-
[解決済み] Sinatraがファイルを変更するたびに自動で再読み込みするようにするには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Rubyでコンソールから入力を読み込む?
-
[解決済み] 2つのハッシュを比較するにはどうすればよいですか?
-
[解決済み] ルビー 負の数を正の数に変換する?
-
[解決済み] doブロックと中括弧{}の使い分け
-
[解決済み] Ruby の文字列から最後の n 文字を抽出する。
-
[解決済み] rspecでテストグループを無効にする?
-
[解決済み] Ruby 配列を関数の引数に変換する
-
[解決済み] Rubyで、selectとmapを組み合わせたArrayメソッドはありますか?
-
[解決済み] Rubyで2つの配列のマージとインターリーブ
-
[解決済み] Rubyのモジュール/ミキシンからクラスメソッドを継承する