¿Cuáles son todas las formas comunes de leer un archivo en Ruby?
Por ejemplo, aquí hay un método:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Sé que Ruby es extremadamente flexible. ¿Cuáles son los beneficios / inconvenientes de cada enfoque?
Respuestas:
También es posible cerrar explícitamente el archivo después de lo anterior (pase un bloque para cerrarlo
open
por usted):fuente
foreach
lugar deopen
y prescinda deleach_line
bloque.f.each { |line| ... }
yf.each_line { |line| ... }
parecen tener el mismo comportamiento (al menos en Ruby 2.0.0).La forma más fácil si el archivo no es demasiado largo es:
De hecho,
IO.read
oFile.read
cierre automáticamente el archivo, por lo que no es necesario usarloFile.open
con un bloque.fuente
IO.read
oFile.read
también cierra automáticamente el archivo, aunque su redacción hace que parezca que no.Tenga cuidado con los archivos "sorber". Ahí es cuando lees todo el archivo a la memoria a la vez.
El problema es que no escala bien. Podría estar desarrollando código con un archivo de tamaño razonable, luego ponerlo en producción y de repente descubrir que está tratando de leer archivos que miden en gigabytes, y su host se está congelando mientras intenta leer y asignar memoria.
La E / S línea por línea es muy rápida y casi siempre tan efectiva como el sorber. Es sorprendentemente rápido en realidad.
Me gusta usar:
o
El archivo hereda de IO y
foreach
está en IO, por lo que puede usar cualquiera.Tengo algunos puntos de referencia que muestran el impacto de tratar de leer archivos grandes a través
read
de E / S línea por línea en " ¿Por qué no es una buena práctica" sorber "un archivo? ".fuente
Puede leer el archivo de una vez:
Cuando el archivo es grande, o puede ser grande, generalmente es mejor procesarlo línea por línea:
Sin embargo, a veces desea acceder al identificador de archivo o controlar las lecturas usted mismo:
En el caso de archivos binarios, puede especificar un separador nulo y un tamaño de bloque, así:
Finalmente, puede hacerlo sin bloqueo, por ejemplo, al procesar múltiples archivos simultáneamente. En ese caso, el archivo debe cerrarse explícitamente (mejorado según el comentario de @antinome):
Referencias: API de archivo y la API de IO .
fuente
for_each
en Archivo o IO. Usar en suforeach
lugar.while
lugar deloop
usarensure
para garantizar que el archivo se cierre incluso si se produce una excepción. Como esto (reemplace punto y coma con saltos de línea):begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
.Un método simple es usar
readlines
:Cada línea en el archivo de entrada será una entrada en la matriz. El método se encarga de abrir y cerrar el archivo por usted.
fuente
read
cualquier variante, esto arrastrará todo el archivo a la memoria, lo que puede causar problemas importantes si el archivo es más grande que la memoria disponible. Además, debido a que es una matriz, Ruby tiene que crear la matriz, lo que ralentiza el proceso adicionalmente.http://www.ruby-doc.org/core-1.9.3/IO.html#method-c-read
fuente
Usualmente hago esto:
Esto le dará todo el texto como un objeto de cadena. Funciona solo bajo Ruby 1.9.
fuente
devuelve las últimas n líneas de your_file.log o .txt
fuente
Una forma aún más eficiente es la transmisión pidiendo al núcleo del sistema operativo que abra un archivo y luego lea los bytes poco a poco. Al leer un archivo por línea en Ruby, los datos se toman del archivo 512 bytes a la vez y luego se dividen en "líneas".
Al almacenar en búfer el contenido del archivo, el número de llamadas de E / S se reduce al dividir el archivo en fragmentos lógicos.
Ejemplo:
Agregue esta clase a su aplicación como un objeto de servicio:
Llámalo y pasa el
:each
método un bloque:Lea sobre esto aquí en esta publicación detallada:
Ruby Magic Slurping & Streaming Files por AppSignal
fuente
Creo que este método es el más "poco común". Tal vez sea un poco complicado, pero funciona si
cat
está instalado.fuente
content = File.read(filename)