Es de conocimiento común en la mayoría de los lenguajes de programación que el flujo para trabajar con archivos es abrir-usar-cerrar. Sin embargo, vi muchas veces en códigos ruby llamadas File.open incomparables y, además, encontré esta joya de conocimiento en los documentos ruby:
Los flujos de E / S se cierran automáticamente cuando son reclamados por el recolector de basura.
irc amigable con darkredandyellow aborda el problema:
[17:12] sí, y también, el número de descriptores de archivo generalmente está limitado por el sistema operativo
[17:29] Supongo que puede quedarse sin descriptores de archivo disponibles antes de que el recolector de basura limpie arriba. en este caso, es posible que desee utilizar cerrarlos usted mismo. "Reclamado por el recolector de basura". significa que el GC actúa en algún momento en el futuro. y es caro. muchas razones para cerrar archivos explícitamente.
- ¿Necesitamos cerrar explícitamente
- En caso afirmativo, ¿por qué se cierra automáticamente el GC?
- Si no, ¿por qué la opción?
$ ulimit -n => 1024
solo es alto cuando haces un trabajo simple. ¡El mal hábito causará un gran problema algún día!Respuestas:
¿Puede dar un ejemplo? Solo veo eso en el código escrito por novatos que carecen del "conocimiento común en la mayoría de los lenguajes de programación de que el flujo para trabajar con archivos es abrir-usar-cerrar".
Los Rubyistas experimentados cierran explícitamente sus archivos o, más idiomáticamente, usan la forma de bloque de
File.open
, que cierra automáticamente el archivo para usted. Su implementación básicamente se parece a esto:Los guiones son un caso especial. Los scripts generalmente se ejecutan tan cortos y usan tan pocos descriptores de archivo que simplemente no tiene sentido cerrarlos, ya que el sistema operativo los cerrará de todos modos cuando el script salga.
Si.
Porque una vez que ha recopilado el objeto, ya no hay forma de que cierre el archivo y, por lo tanto, filtrará descriptores de archivo.
Tenga en cuenta que no es el recolector de basura el que cierra los archivos. El recolector de basura simplemente ejecuta cualquier finalizador para un objeto antes de recolectarlo. Da la casualidad de que la
File
clase define un finalizador que cierra el archivo.Porque la memoria desperdiciada es barata, pero los descriptores de archivos desperdiciados no lo son. Por lo tanto, no tiene sentido vincular la vida útil de un descriptor de archivo con la vida útil de una parte de la memoria.
Simplemente no puede predecir cuándo se ejecutará el recolector de basura. Ni siquiera se puede predecir si se ejecutará en absoluto : si nunca se agota la memoria, el recolector de basura nunca se quedará, por tanto, el finalizador nunca se quedará, por lo tanto, el archivo nunca se cerró.
fuente
ensure
,rescue
yraise
no son necesarios en absoluto.ensure
sinrescue
. Y no puede simplemente tragarse la excepción silenciosamente, debe propagarla a la persona que llama, después de haber cerrado el archivo. De todos modos, recuérdame de nuevo en mayo de 2015 :-DSiempre debe cerrar los descriptores de archivos después de su uso, eso también los eliminará. A menudo, la gente usa File.open o un método equivalente con bloques para manejar la vida útil del descriptor de archivo. Por ejemplo:
En ese ejemplo, el archivo se cierra automáticamente.
fuente
Según http://ruby-doc.org/core-2.1.4/File.html#method-c-open
Por lo tanto, se cerrará automáticamente cuando finalice el bloque : D
fuente
fuente
Podemos usar la
File.read()
función para leer el archivo en ruby ... como,en este ejemplo
file_variable
puede tener el valor completo de ese archivo ...fuente