manipulacion arreglos archivos ruby file-io

arreglos - file ruby



¿Cuáles son todas las formas comunes de leer un archivo en Ruby? (10)

¿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?


Generalmente hago esto:

open(path_in_string, &:read)

Esto le dará todo el texto como un objeto de cadena. Funciona solo bajo Ruby 1.9.


La forma más fácil si el archivo no es demasiado largo es:

puts File.read(file_name)

De hecho, IO.read o File.read cierran automáticamente el archivo, por lo que no es necesario utilizar File.open con un bloque.


Puedes leer el archivo de una vez:

content = File.readlines ''file.txt'' content.each_with_index{|line, i| puts "#{i+1}: #{line}"}

Cuando el archivo es grande, o puede ser grande, generalmente es mejor procesarlo línea por línea:

File.foreach( ''file.txt'' ) do |line| puts line end

A veces, usted desea acceder al identificador de archivos o controlar las lecturas usted mismo:

File.open( ''file.txt'' ) do |f| loop do break if not line = f.gets puts "#{f.lineno}: #{line}" end end

En el caso de archivos binarios, puede especificar un separador nulo y un tamaño de bloque, como:

File.open(''file.bin'', ''rb'') do |f| loop do break if not buf = f.gets(nil, 80) puts buf.unpack(''H*'') end end

Finalmente, puede hacerlo sin bloqueos, por ejemplo, al procesar varios archivos simultáneamente. En ese caso, el archivo debe cerrarse explícitamente (mejorado según el comentario de @antinome):

begin f = File.open ''file.txt'' while line = f.gets puts line end ensure f.close end

Referencias: API de archivos y la API de IO .


Tenga cuidado con los archivos "slurping". Ahí es cuando lees todo el archivo en la memoria a la vez.

El problema es que no se escala bien. Podría estar desarrollando código con un archivo de tamaño razonable, luego póngalo en producción y de repente descubra que está intentando leer archivos que miden en gigabytes, y su host se está congelando cuando intenta leer y asignar memoria.

La E / S línea por línea es muy rápida, y casi siempre tan efectiva como el sorbido. Es sorprendentemente rápido en realidad.

Me gusta usar:

IO.foreach("testfile") {|x| print "GOT ", x }

o

File.foreach(''testfile'') {|x| print "GOT", x }

El archivo se hereda de IO y foreach está en IO, por lo que puede usar cualquiera de los dos.

Tengo algunos puntos de referencia que muestran el impacto de tratar de leer archivos grandes a través de E / S de read frente a línea en " ¿Por qué es" una buena práctica " no es una buena práctica? ".


Un método simple es usar readlines :

my_array = IO.readlines(''filename.txt'')

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.


Una forma aún más eficiente es la transmisión al pedir al núcleo del sistema operativo que abra un archivo, y luego leer los bytes poco a poco. Al leer un archivo por línea en Ruby, los datos se toman del archivo de 512 bytes a la vez y se dividen en "líneas" después de eso.

Al almacenar en búfer el contenido del archivo, el número de llamadas de E / S se reduce mientras se divide el archivo en partes lógicas.

Ejemplo:

Agrega esta clase a tu aplicación como un objeto de servicio:

class MyIO def initialize(filename) fd = IO.sysopen(filename) @io = IO.new(fd) @buffer = "" end def each(&block) @buffer << @io.sysread(512) until @buffer.include?($/) line, @buffer = @buffer.split($/, 2) block.call(line) each(&block) rescue EOFError @io.close end end

Llámalo y pasa el :each método un bloque:

filename = ''./somewhere/large-file-4gb.txt'' MyIO.new(filename).each{|x| puts x }

Lea sobre esto aquí en este post detallado:

Ruby Magic Slurping & Streaming Files de AppSignal


devuelve las últimas n líneas desde tu_archivo.log o .txt

path = File.join(Rails.root, ''your_folder'',''your_file.log'') last_100_lines = `tail -n 100 #{path}`


File.open("my/file/path", "r") do |f| f.each_line do |line| puts line end end # File is closed automatically at end of block

También es posible cerrar explícitamente el archivo después de lo anterior (pasar un bloque para open cierra por usted):

f = File.open("my/file/path", "r") f.each_line do |line| puts line end f.close


content = `cat file`

Creo que este método es el más "raro". Tal vez sea un poco complicado, pero funciona si se instala cat .