Escritura

El Método write

Los objetos File tienen dos formas del método write:

void    write(String)
void    write(String, String)
ambas escriben su primer argumento al fichero. El segundo argumento especifica la codificación a usar.

generaciondecodigos@nereida:~/src/groovy/files$ cat -n writeFile.groovy
     1  #!/usr/bin/env groovy
     2  // write the text in the file
     3  new File("myFile.txt").write("Hello world")

El Método write y la Codificación

Veamos otro ejemplo:

Hello worldgeneraciondecodigos@nereida:~/src/groovy/files$ cat -n writeEuro.groovy
     1  #!/usr/bin/env groovy
     2  // you may specify the encoding
     3  new File("myFile.txt").write("\u20AC is the symbol for the Euro currency", 'UTF-8')

Al ejecutar produce la salida:

generaciondecodigos@nereida:~/src/groovy/files$ ./writeEuro.groovy
generaciondecodigos@nereida:~/src/groovy/files$ cat myFile.txt
€ is the symbol for the Euro

Sobreescritura

Sucesivas llamadas al método write sobreescriben el fichero:

groovy:000> f = new File("fileWrite.txt")
===> fileWrite.txt
groovy:000> f.write("Hello 1\n")
===> null
groovy:000> "cat fileWrite.txt".execute().text
===> Hello 1

groovy:000> f.write("Hello 2\n")
===> null
groovy:000> "cat fileWrite.txt".execute().text
===> Hello 2
El método execute() arranca un proceso que ejecuta la cadena como comando. Retorna un objeto java.lang.UNIXProcess que tiene atributos errorStream, inputStream y outputStream.

El Método append

Usaremos append si se quieren concatenar las salidas:

groovy:000> f = new File("Chum.txt")
===> Chum.txt
groovy:000> f.append("Hello World!\n")
===> null
groovy:000> f.append("... and Goodbye!\n")
===> null
groovy:000> "cat -n Chum.txt".execute().text
===>      1     Hello World!
     2  ... and Goodbye!

Copia de un Fichero

El siguiente programa copia los contenidos de un fichero en otro:

generaciondecodigos@nereida:~/src/groovy/files$ cat -n copy.groovy
     1  #!/usr/bin/env groovy
     2  if (args.length != 2) {
     3    println "Usage:\n\tcopy file.input file.output"
     4    System.exit 1
     5  }
     6
     7  source = new File(args[0])
     8  if (!source.canRead()) {
     9      println "Can't find file $source!"
    10      System.exit 2
    11  }
    12
    13  target = new File(args[1])
    14
    15  try {
    16    target.withWriter { file ->
    17        source.eachLine { line ->
    18            file.writeLine(line)
    19        }
    20    }
    21  } catch(e) {
    22    println "Can't create copy of $source in $target"
    23    System.exit 3
    24  }

Veamos el resultado de algunas ejecuciones:

generaciondecodigos@nereida:~/src/groovy/files$ ./copy.groovy input.txt output.txt
generaciondecodigos@nereida:~/src/groovy/files$ diff input.txt output.txt
generaciondecodigos@nereida:~/src/groovy/files$
generaciondecodigos@nereida:~/src/groovy/files$ echo $?
0
generaciondecodigos@nereida:~/src/groovy/files$ ./copy.groovy doesnotexist.txt output.txt
Can't find file doesnotexist.txt!
generaciondecodigos@nereida:~/src/groovy/files$ echo $?
2
generaciondecodigos@nereida:~/src/groovy/files$ ./copy.groovy input.txt /root/output.txt
Can't create copy of input.txt in /root/output.txt
generaciondecodigos@nereida:~/src/groovy/files$ echo $?
3
generaciondecodigos@nereida:~/src/groovy/files$ ./copy.groovy input.txt a b
Usage:
        copy file.input file.output
generaciondecodigos@nereida:~/src/groovy/files$ echo $?
1

El Método withWriter, la Clase BufferedWriter y el Método writeLine

El método withWriter

public Object withWriter(Closure)

crea un nuevo objeto BufferedWriter para este fichero. Dicho objeto se le pasa a la clausura que constituye el argumento, garantizándose que cuando la clausura termina el buffer ha sido completamente volcado (flushed) y cerrado.

Los objetos BufferedWriter han sido concebidos para escribir texto a un flujo de entrada/salida usando buffering de manera que la escritura sea eficiente. Los objetos BufferedWriter disponen del método

void    writeLine(String)
el cual escribe el texto añadiendo al final una nueva línea:
    16    target.withWriter { file ->
    17        source.eachLine { line ->
    18            file.writeLine(line)
    19        }
    20    }

El Método eachLine de los Objetos File

La clausura que recibe como último argumento eachLine puede ser llamada también con dos parámetros. En ese caso el segundo argumento es el número de línea. Podemos modificar entonces las líneas de copia en el anterior ejemplo de esta forma:

 target.withWriter { file ->
      source.eachLine { line, num ->
          file.writeLine("$num: $line")
      }
  }
y obtendremos un programa que numera las líneas copiadas:
generaciondecodigos@nereida:~/src/groovy/files$ ./copywithnum.groovy input.txt output.txt
generaciondecodigos@nereida:~/src/groovy/files$ diff input.txt output.txt
1,3c1,3
< an
< input
< file
---
> 1: an
> 2: input
> 3: file
El método eachLine retorna el valor retornado por la última ejecución de la clausura.

Es posible pasarle como parámetros la codificación y el número de línea inicial:

public Object eachLine(String, int, Closure)

Parámetros:
  1. charset - Abre el fichero con el charset indicado
  2. firstLine - Indica la primera línea (por defecto es 1)
  3. closure - La clausura recibe dos argumentos. El primero es la línea, el segundo el número de línea

Copia: Otra forma de hacerla

Esta es una solución alternativa en la que se usa el método append del fichero target prescindiendo de withWriter. En el caso de que el fichero target ya exista lo vaciamos:

generaciondecodigos@nereida:~/Lgroovy/files$ cat -n copy3.groovy 
     1  #!/usr/bin/env groovy
     2  if (args.length < 2) return 
     3  
     4  source = new File(args[0])
     5  if (source.canRead()) {
     6    target = new File(args[1])
     7    if (target.exists()) {
     8      target.delete()
     9    }
    10    try {
    11          source.eachLine { line ->
    12              target.append("$line\n")
    13          }
    14    }
    15    catch(e) {
    16      println "Can't write in $target!"
    17    }
    18  }
    19  else {
    20    println "File $source not found!"
    21  }



Subsecciones
Casiano Rodríguez León
2010-04-30