ruby file-io

File.open, open y IO.foreach en Ruby, ¿cuál es la diferencia?



ruby raise (1)

Hay diferencias importantes entre esas 3 opciones.

File.open("file").each_line { |line| puts line }

  • File.open abre un archivo local y devuelve un objeto de archivo
  • el archivo permanece abierto hasta que llame a IO#close de él

open("file").each_line { |line| puts line }

Kernel.open mira la cadena para decidir qué hacer con ella.

open(".irbrc").class # => File open("http://google.com/").class # => StringIO File.open("http://google.com/") # => Errno::ENOENT: No such file or directory - http://google.com/

En el segundo caso, el objeto StringIO devuelto por Kernel#open realmente contiene el contenido de http://google.com/ . Si Kernel#open devuelve un objeto File , permanece abierto hasta que se IO#close el IO#close .

IO.foreach("file") { |line| puts line }

  • IO.foreach abre un archivo, llama al bloque dado para cada línea que lee y luego cierra el archivo.
  • No tiene que preocuparse por cerrar el archivo.

File.read("file").each { |line| puts line }

No mencionó esta opción, pero esta es la que usaría en la mayoría de los casos.

  • File.read lee un archivo completamente y lo devuelve como una cadena.
  • No tiene que preocuparse por cerrar el archivo.
  • En comparación con IO.foreach esto deja en claro que se trata de un archivo.
  • La complejidad de la memoria para esto es O (n). Si sabe que está tratando con un archivo pequeño, esto no es un inconveniente. Pero si puede ser un archivo grande y usted sabe que la complejidad de su memoria puede ser menor que O (n), no use esta opción.

Falla en esta situación:

s= File.read("/dev/zero") # => never terminates s.each …

Rhode Island

ri es una herramienta que te muestra la documentación de ruby. Lo usas así en tu caparazón.

ri File.open ri open ri IO.foreach ri File#each_line

Con esto puedes encontrar casi todo lo que escribí aquí y mucho más.

Todas las siguientes API hacen lo mismo: abrir un archivo y llamar a un bloque para cada línea. ¿Hay alguna preferencia que debemos usar uno que otro?

File.open("file").each_line {|line| puts line} open("file").each_line {|line| puts line} IO.foreach("file") {|line | puts line}