103 votes

Ruby's File.open et le besoin de f.close

Il est commun de connaissances, dans la plupart des langages de programmation que le flux de travail avec des fichiers est libre d'utilisation. Pourtant, j'ai vu de nombreuses fois en ruby codes de Fichier incorrect.les appels d'ouverture, et d'ailleurs j'ai trouvé ce petit bijou de connaissances en ruby docs:

I/O les flux sont automatiquement fermés lorsqu'ils sont réclamés par le garbage collector.

darkredandyellow amical irc prendre sur la question:
[17:12] oui, et aussi, le nombre de descripteurs de fichier est généralement limitée par le système d'exploitation
[17:29] je suppose que vous pouvez facilement exécuter de descripteurs de fichier avant de le garbage collector nettoie. dans ce cas, vous pourriez vouloir utiliser les fermer vous-même. "revendiquée par le garbage collector." signifie que le GC actes à un certain moment dans l'avenir. et c'est cher. beaucoup de raisons pour explicitement la fermeture des fichiers.

  1. Devons-nous fermer explicitement
  2. Si oui, alors pourquoi ne le GC autoclose ?
  3. Si non, alors pourquoi l'option?

144voto

Jörg W Mittag Points 153275

J'ai vu de nombreuses fois en ruby codes inégalée File.open appels

Pouvez-vous donner un exemple? Je ne vois jamais que dans le code écrit par les débutants qui manque le "commun des connaissances dans la plupart des langages de programmation que le flux de travail avec des fichiers est ouvert-usage-près".

Connu Rubyists soit explicitement fermer leurs fichiers, ou, plus idiomatique, l'utilisation de la forme du bloc de l' File.open, qui se ferme automatiquement le fichier pour vous. Sa mise en œuvre semble fondamentalement quelque chose comme comme ceci:

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)
rescue
ensure
  f.close
  raise
end

Les Scripts sont un cas particulier. Les Scripts s'exécutent généralement donc, à court, et de l'utiliser si peu de descripteurs de fichiers qu'il n'a tout simplement pas de sens pour les fermer, car le système d'exploitation va se fermer de toute façon lorsque le script se termine.

Devons-nous fermer explicitement?

Oui.

Si oui, alors pourquoi ne le GC autoclose?

Parce que, après qu'il a recueillies l'objet, il n'existe aucun moyen pour vous de fermer le fichier, et de plus, donc à vous de fuites de descripteurs de fichiers.

Notez que ce n'est pas le garbage collector qui ferme les fichiers. Le garbage collector simplement exécute toutes les finaliseurs pour un objet avant de la recueillir. Il se trouve que l' File classe définit un finaliseur qui ferme le fichier.

Si non, alors pourquoi l'option?

Parce que la mémoire gaspillée à bas prix, mais gaspillé des descripteurs de fichiers ne le sont pas. Par conséquent, il n'est pas judicieux de lier la durée de vie d'un descripteur de fichier de la durée de vie de certaines partie de la mémoire.

Vous ne pouvez simplement pas prédire quand le garbage collector sera exécuté. Vous ne pouvez même pas prédire s' il sera exécuté à tous: si vous n'avez jamais à court de mémoire, le garbage collector ne sera jamais exécuté, donc le finaliseur ne sera jamais exécuté, par conséquent, le fichier ne sera jamais fermé.

77voto

Tonttu Points 1313

Vous devez toujours fermer les descripteurs de fichier après utilisation, cela le videra également. Souvent, les gens utilisent File.open ou une méthode équivalente avec des blocs pour gérer la durée de vie du descripteur de fichier. Par exemple:

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

Dans cet exemple, le fichier est fermé automatiquement.

1voto

Satya Points 2222
  1. Oui
  2. Si vous ne le faites pas, ou s'il y a un autre échec
  3. Voir 2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X