Leer y escribir archivos

Veamos cómo podemos leer y escribir archivos de texto con la ayuda de un programa simple: p027leeryescribir.rb

 1 # Abrir un archivo y leer su contenido
 2 # Nota que ya que esta presente un bloque, el archivo
 3 # es cerrado automaticamente cuando se termina la ejecucion
 4 # del bloque
 5 File.open('p014estructuras.rb', 'r') do |f1|
 6   while linea = f1.gets
 7     puts linea
 8   end
 9 end
10 
11 # Crer un archivo y escribir en el
12 File.open('prueba.txt', 'w') do |f2|
13   f2.puts "Creado desde un programa Ruby!"
14 end

El método File.open puede abrir archivos en modos diferentes como:

  • r Sólo lectura. Comienza al inicio del archivo
  • r+ Lectura y escritura. Comienza al inicio del arhivo.
  • w Sólo escritura. Borro el un archivo (si existe) y crea uno nuevo.

En la documentación en línea puedes revisar una lista completa de los modos disponibles.

File.open abre un nuevo archivo si no hay un bloque asociado. Si se proporciona un bloque, el archivo es pasado como argumento y se cierra automáticamente cuando la ejecución del bloque termina. Recuerda que siempre debes cerrar un archivo que abras. En el caso de que abras un archivo para escritura, es particularmente importante y puede prevenir la pérdida de datos.

File implementa el método readlines, que crea un array del contenido completo de un archivo, línea por línea.

open y readlines son métodos de clase definidos en la clase IO, de la que File es subclase. Aún no hemos estudiado clases, objetos ni herencia pero es importante notar que estos dos métodos son heredados por la sub-clase File de la clase IO.

Tarea Escribe un programa en Ruby (p028cambiacontenido) que tome dos archivos de texto, digamos A y B e intercambie sus contenidos. e.d., después de que el programa es ejecutado, A debe tener el contenido de B y B el de A.

Moviéndonos a través de un directorio

El módulo Find soporta el movimiento transversal de un conjunto de archivos proporcionados como argumentos al método find. Si el argumento es un directorio, entonces este y todos los archivos y sub-directorios que contenga serán pasados al método.

 1 require "find"
 2 
 3 Find.find('./') do |f|
 4   tipo = case
 5   when File.file?(f)      : 'F'
 6   when File.directory?(f) : 'D'
 7   else "?"
 8   end
 9   puts "#{tipo}: #{f}"
10 end

Acceso a una posición específica del archivo

Es muy fácil tener acceso a un archivo de manera aleatoria. Digamos que tenemos un archivo de texto llamado hola_mexico.rb, cuyo contenido es el siguiente:

1 puts 'Hola México'

Imagina que necesitamos mostrar el contenido del archivo desde la palabra México. El programa p028aleatorio.rb nos muestro como:

1 f = File.open("hola_mexico.rb")
2 
3 
4 # SEEK_SET - Busca una ubicacion absoluta dada por numero en el parametro
5 
6 f.seek(11, IO::SEEK_SET)
7 print f.readline
8 f.close

El método seek de la clase IO busca una posición en el archivo de acuerdo al primer parámetro pasado al método y al valor del segundo parámetro, que puede ser:

  • IO::SEEK_CUR- Busca de acuerdo al primer parámetro más la posición actual
  • IO::SEEK_END- Busca de acuerdo al primer parámetro más el final del archivo
  • IO::SEEK_SET- Busca una posición absoluta dada por el primer parámetro

¿Ruby permite la serialización de objetos?

Con Java podemos serializar objetos, lo que permite guardarlos en algún lugar y reconstituirlos cuando sea necesario. Ruby llama a este tipo de serialización marshalling. Guardar un objeto y algunos o todos sus componentes se logra usando el método Marshal.dump. Más tarde puedes reconstituir el objeto usando Marshal.load Ruby utiliza el marshalling para guardar datos de sesiones.

Resumen

Revisa la lista de todos los puntos importantes que necesitas recordar después de haber completado los siguientes temas: Rangos, Blocks y Procs, Números aleatorios, Arrchivos de texto.