0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

ファイル操作の基礎:閉じたファイルオブジェクトと再オープン時のエラー

Posted at

閉じたファイルオブジェクトに対する操作

以下のコードは、ファイルを書き込み用に開き、テキストを書き込む処理です。
最後にファイルを閉じる操作を入れないと、ファイルを開くために確保したメモリが解放されなかったり、整合性と排他制御の問題からファイル操作が正常に行われなかったりします。

# File.openでファイルを開き、File.closeで閉じる
file = File.open("example.txt", "w")
file.puts "Hello, world!"
file.close

# もしくはブロックで囲むことで、勝手にファイルが閉じられる
File.open("example.txt", "w").do |file|
  file.puts "Hello, world!"
end

ここまでは問題ないですが、一度ファイルを閉じた後に対象のファイルオブジェクトを再利用しようとすると、当然怒られます。

file = File.open("example.txt", "w")
file.write("Hello, world!")
file.close

begin
  file.read
rescue IOError => e
  puts "Error: #{e.message}"
end

# Error: closed stream

# File.openに先程のファイルオブジェクトのパスに指定した場合も
# 閉じたファイルオブジェクトを再利用しているのでエラー
begin
  file = File.open(file.path, "r")
rescue IOError => e
  puts "Error: #{e.message}"
end

# Error: closed stream

解決法

閉じたファイルを操作したいなら、閉じたファイルオブジェクトは使わず、ファイルパスから新しいファイルオブジェクトを再生成することで、エラーを回避できます。

file = File.open("example.txt", "w")
file.write("Hello, world!")
file.close

begin
  new_file = File.open("example.txt", "r")
  content = new_file.read
  puts content
  new_file.close
rescue IOError => e
  puts "Error: #{e.message}"
end

一時ファイルオブジェクトとの挙動の違い

ちなみに Tempfile クラスで作成した一時ファイルオブジェクトの場合は少し挙動が異なります。

require 'tempfile'

temp_file = Tempfile.new("example")
temp_file.write("Hello, Tempfile!")
temp_file.close

begin
  new_temp_file = File.open(temp_file.path, "r")
  content = new_temp_file.read
  puts content
  new_temp_file.close
rescue IOError => e
  puts "Error: #{e.message}"
end

一時ファイルを閉じた後で再度操作するには、新しいファイルオブジェクトを作成するのは同じですが、Tempfile の場合、閉じた一時ファイルオブジェクトからでもファイルパスを参照できます。
よって、そのパスから File.open で再度ファイルオブジェクトを作成できます。

まとめ

基本は必要なファイル操作を実施してから、最後にファイルを閉じるべきだと思います。
ただ、どうしても再度ファイル操作が必要になる場合は、閉じたファイルオブジェクトを再利用せずに、新しいファイルオブジェクトを作成することで、エラーを回避できそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?