Pertanyaan File Ruby.open dan kebutuhan untuk f.close


Sudah menjadi pengetahuan umum di sebagian besar bahasa pemrograman bahwa alur untuk bekerja dengan file adalah buka-pakai-tutup. Namun saya melihat berkali-kali dalam kode ruby ​​panggilan File.open yang tak tertandingi, dan selain itu saya temukan permata pengetahuan ini di ruby ​​docs:

I / O stream secara otomatis ditutup ketika mereka diklaim oleh pengumpul sampah.

darkredandyellow irc ramah mengambil tentang masalah ini:
[17:12] ya, dan juga, jumlah pendeskripsi file biasanya dibatasi oleh OS
[17:29] Saya berasumsi Anda dapat dengan mudah kehabisan deskriptor file yang tersedia sebelum pengumpul sampah membersihkan. dalam hal ini, Anda mungkin ingin menggunakan menutupnya sendiri. "Diklaim oleh pengumpul sampah." berarti GC bertindak di beberapa titik di masa depan. dan itu mahal. banyak alasan untuk menutup file secara eksplisit.

  1. Apakah kita perlu menutup secara eksplisit
  2. Jika ya, mengapa GC autoclose?
  3. Jika tidak maka mengapa pilihannya?

76
2018-01-25 15:38


asal


Jawaban:


Saya melihat berkali-kali dalam kode rubi yang tak tertandingi File.open panggilan

Bisakah Anda memberi contoh? Saya hanya pernah melihat bahwa dalam kode yang ditulis oleh para pemula yang kekurangan "pengetahuan umum dalam sebagian besar bahasa pemrograman bahwa alur untuk bekerja dengan file terbuka-gunakan-tutup".

Rubyist yang berpengalaman baik secara eksplisit menutup file mereka, atau, lebih idiomatis, menggunakan bentuk blok File.open, yang secara otomatis menutup file untuk Anda. Implementasinya pada dasarnya terlihat seperti ini:

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

Skrip adalah kasus khusus. Skrip umumnya berjalan sangat singkat, dan menggunakan begitu sedikit deskripsi file sehingga tidak masuk akal untuk menutupnya, karena sistem operasi akan menutupnya ketika skrip selesai.

Apakah kita perlu menutup secara eksplisit?

Iya nih.

Jika ya, mengapa GC autoclose?

Karena setelah mengumpulkan objek, tidak ada cara bagi Anda untuk menutup file lagi, dan dengan demikian Anda akan membocorkan deskriptor file.

Perhatikan bahwa itu bukan garbage collector yang menutup file. Pengumpul sampah hanya mengeksekusi finalis apa pun untuk objek sebelum mengumpulkannya. Kebetulan bahwa File class mendefinisikan finalizer yang menutup file.

Jika tidak maka mengapa pilihannya?

Karena memori yang terbuang itu murah, tetapi deskriptor file yang terbuang tidak. Oleh karena itu, tidak masuk akal untuk mengikat umur suatu deskriptor file untuk seumur hidup beberapa potongan memori.

Anda tidak bisa memprediksi kapan pengumpul sampah akan lari. Anda bahkan tidak bisa memprediksi jika itu akan berjalan sama sekali: jika Anda tidak pernah kehabisan memori, garbage collector tidak akan pernah berjalan, oleh karena itu finalis tidak akan pernah berjalan, oleh karena itu file tidak akan pernah ditutup.


113
2018-01-25 16:04



Anda harus selalu menutup deskriptor file setelah digunakan, yang juga akan menyiramnya. Sering digunakan orang File.open atau metode setara dengan blok untuk menangani umur deskriptor file. Sebagai contoh:

File.open('foo', 'w') do |f|
    f.write "bar"
end

Dalam contoh itu, file ditutup secara otomatis.


62
2018-01-25 15:47



  1. iya nih
  2. Jika Anda tidak, atau jika ada beberapa kegagalan lainnya
  3. Lihat 2.

1
2018-01-25 15:40



Menurut http://ruby-doc.org/core-2.1.4/File.html#method-c-open

Tanpa blok terkait, File.open adalah sinonim untuk :: baru. Jika itu   blok kode opsional diberikan, itu akan melewati file yang dibuka sebagai argumen   dan objek File secara otomatis akan ditutup ketika blok   berakhir. Nilai blok akan dikembalikan dari File.open.

Karena itu, akan secara otomatis ditutup ketika blok berakhir : D


1
2018-05-26 17:31



Kami bisa menggunakan File.read() berfungsi untuk membaca file di ruby ​​..... seperti,

file_variable = File.read("index.html")

dalam contoh ini file_variable dapat memiliki nilai penuh dari file itu ....


-1
2018-01-10 12:09