¿Cómo escribir en un archivo en Ruby?

572

Necesito leer los datos de la base de datos y luego guardarlos en un archivo de texto.

¿Cómo puedo hacer eso en Ruby? ¿Hay algún sistema de gestión de archivos en Ruby?

ohana
fuente

Respuestas:

179

La clase Ruby File le dará los entresijos de ::newy ::openpero su padre, la clase IO , profundiza en #ready #write.

jdl
fuente
66
Gracias @ Geoff. Es bueno ver a los nuevos usuarios limpiar preguntas y respuestas obsoletas. Hace para un mejor sitio en general.
jdl
77
Esto me parece irónico. La respuesta está muy bien documentada ... pero ahora un año después, esta pregunta es el primer éxito en Google. Cuando se hizo la pregunta, puede parecer que el OP estaba dedicando poco esfuerzo, pero ahora en lo que respecta a Google, esta es la mejor fuente.
Jeff
77
Probablemente porque todo lo que realmente necesitas saber está aquí. La mía es la respuesta "enseñar a un hombre a pescar" para aquellos que quieran leer los detalles más finos, y hay muchas respuestas de "dar a un hombre un pez" aquí también para personas que solo quieren cortar y pegar. No es sorprendente que esta combinación termine bien clasificada en Google.
jdl
1
Entonces, para ser justos, trabajo en muchos idiomas diferentes, lo que significa que rara vez me acuerdo de recordar la sintaxis de uno específico. Lo busqué en Google varias veces, y siempre me desplazo más allá de esta respuesta, a la siguiente, porque cuando busco en Google StackOverflow, generalmente solo estoy buscando un pez maldito. : p Sinceramente, es bueno tener ambos. Quizás algún día estaré haciendo suficiente Ruby de una vez para que me preocupe por los detalles.
user435779
2
Esto no responde la pregunta. Simplemente señala las dos clases que contienen la mayoría de los métodos para hacer E / S, y no menciona la conexión con la base de datos. Eso estaría bien como comentario, pero difícilmente califica como respuesta. Me doy cuenta de que el OP y los muchos lectores que votaron por esta respuesta no están de acuerdo, y francamente no entiendo lo que estaban pensando.
Cary Swoveland
929

¿Estás buscando lo siguiente?

File.open(yourfile, 'w') { |file| file.write("your text") }
Todd R
fuente
8
yourfilees una variable que contiene el nombre del archivo a escribir.
B Seven
17
Alternativamente: f = File.open ('nombre', 'w'); f.write ('texto'); f.close
vish
55
@vish: No recomendaría esta solución ya que el descriptor de archivo se dejaría abierto si se f.writegenera una Excepción.
nbarraille
289
Corto y dulce:File.write('filename', 'content')
Benjamin Oakes
14
Incluso más corto y documentado:IO.write('filename', 'content')
Tailandés
636

Puedes usar la versión corta:

File.write('/path/to/file', 'Some glorious content')

Devuelve la longitud escrita; ver :: escribir para más detalles y opciones.

Para agregar al archivo, si ya existe, use:

File.write('/path/to/file', 'Some glorious content', mode: 'a')
Sébastien Le Callonnec
fuente
14
Para su información, este método abreviado solo funciona a partir de Ruby 1.9.3. No existe tal método en ninguna versión anterior de 1.9 o 1.8. En ese caso, debe utilizar el método de bloqueo más largo publicado por @mvndaai
Andrew Burns
13
FYI esto cierra correctamente el archivo cuando haya terminado.
Freedom_Ben
2
Los documentos de la clase IO dicen que cierra el archivo
nruth
77
¿Esto se agregará a un archivo o simplemente lo sobrescribirá?
Joshua Pinter
8
@JoshPinter: se sobrescribe.
mklement0
248

Este es el enfoque preferido en la mayoría de los casos:

 File.open(yourfile, 'w') { |file| file.write("your text") }

Cuando se pasa un bloque a File.open, el objeto Archivo se cerrará automáticamente cuando el bloque termine.

Si no pasa un bloque a File.open, debe asegurarse de que el archivo esté cerrado correctamente y que el contenido se haya escrito en el archivo.

begin
  file = File.open("/tmp/some_file", "w")
  file.write("your text") 
rescue IOError => e
  #some error occur, dir not writable etc.
ensure
  file.close unless file.nil?
end

Lo puedes encontrar en la documentación :

static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE io = rb_class_new_instance(argc, argv, klass);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, io, io_close, io);
    }
    return io;
}
Tombart
fuente
Sí, usando la sintaxis de bloque con {| archivo | ....} cerrará el archivo cuando se cierre el bloque.
wesgarrison
Genial, gracias. No estaba seguro de eso. Aquí hay más información sobre bloques y File.open blog.rubybestpractices.com/posts/rklemme/ ... también se menciona en la documentación oficial
Tombart
1
Solo algo ruby ​​way-ish: nil es un objeto, por lo que para verificar si un archivo es nulo, le pregunta al objeto en lugar de comparar (file.nil? En lugar de file == nil)
JCabello
@JCabello seguro, ese es definitivamente un enfoque más parecido a Ruby, ¡gracias!
Tombart
finalmente, una respuesta que muestra que también se debe verificar el estado del archivo y cómo manejarlo, y no solo un revestimiento que solo muestra la llamada abierta.
Nasser
115

La respuesta de Zambri encontrada aquí es la mejor.

File.open("out.txt", '<OPTION>') {|f| f.write("write your stuff here") }

donde sus opciones <OPTION>son:

r- Solo lectura. El archivo debe existir.

w - Crear un archivo vacío para escribir.

a - Agregar a un archivo. El archivo se crea si no existe.

r+- Abra un archivo para actualizar tanto la lectura como la escritura. El archivo debe existir.

w+ - Cree un archivo vacío para leer y escribir.

a+- Abra un archivo para leer y agregar. El archivo se crea si no existe.

En su caso, wes preferible.

mvndaai
fuente
Me sorprende que una respuesta que ciertamente copia otra respuesta pueda recibir más de 100 votos a favor. Puedo ver publicar la primera oración como un comentario sobre la pregunta, pero eso es todo.
Cary Swoveland
@CarySwoveland Estoy de acuerdo contigo. El verdadero problema es que una de las dos preguntas debería haberse marcado como duplicado hace mucho tiempo. Copié la respuesta porque una vez que encontré la pregunta que Zanbri había respondido y las siguientes veces, cuando necesitaba la misma información, primero encontré esta pregunta y tuve que descubrir cómo llegar a la otra pregunta. Eventualmente, pensé que sería más fácil tener su respuesta aquí también. Me vinculé a su respuesta con tanta esperanza que la gente haría clic y le daría un voto positivo también.
mvndaai
31

Para aquellos de nosotros que aprendemos con el ejemplo ...

Escribir texto en un archivo como este:

IO.write('/tmp/msg.txt', 'hi')

INFORMACIÓN ADICIONAL ...

Léelo de nuevo así

IO.read('/tmp/msg.txt')

Con frecuencia, quiero leer un archivo en mi portapapeles ***

Clipboard.copy IO.read('/tmp/msg.txt')

Y otras veces, quiero escribir lo que está en mi portapapeles en un archivo ***

IO.write('/tmp/msg.txt', Clipboard.paste)

*** Asume que tienes instalada la gema del portapapeles

Ver: https://rubygems.org/gems/clipboard

l3x
fuente
1
Tenga cuidado con la IO.writeopción de sobrescribir el contenido del archivo en lugar de agregar. Anexar con IO.write es un poco tedioso.
fguillen
¿No estás seguro de qué estás hablando? El comando IO.write no necesita esa opción para escribir en un archivo. Tendría cuidado de guardar el archivo en el directorio / tmp o en el directorio actual; De lo contrario, es posible que vea un Errno::ENOENT: No such file or directory @ rb_sysopenmensaje y el archivo creado con un tamaño de 0 bytes.
l3x
25

Para destruir el contenido anterior del archivo, escriba una nueva cadena en el archivo:

open('myfile.txt', 'w') { |f| f << "some text or data structures..." } 

Para adjuntar a un archivo sin sobrescribir su contenido anterior:

open('myfile.txt', "a") { |f| f << 'I am appended string' } 
Marko Tunjic
fuente