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")
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
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 2El 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
.
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!
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
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 }
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: fileEl 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:
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 }