Si buscáis por Internet encontraréis muchas formas distintas de hacerlo usando distintos tipos. Esto es debido a que hay distintas implementaciones de las clases
Reader
y Writer
:- Unas permiten especificar el soporte (no tiene por qué usarse un fichero, podríamos leer y escribir de un socket web o un buffer de datos cualquiera)
- Unas mejoran el rendimiento del ancho del buffer
- Unas están especializadas en guardar texto y otras para datos en crudo (raw)
- Algunos tienen métodos particulares que nos pueden resultar útiles y no pertenecen a las interfaces (como
newLine()
) - Además hay que sumar las distintas librerías que hay para facilitar el tratamiento de estas operaciones como Apache common o guava.
Por todo lo anterior y desde mi punto de vista, voy a usar la forma más eficiente y flexible para hacer operaciones con texto sobre ficheros:
- Usaré sólo Java Nativo.
- Usaré
BufferedReader
/BufferedWriter
porque me va a encapsular unReader
/Writer
para mejorar el rendimiento en los accesos al disco (en cada acceso va a usar el buffer completo y por tanto necesitará menos operaciones de acceso) - Usaré un
InputStreamReader
/OutputStreamWriter
porque me van a permitir especificar la codificación de mi texto (usaré UTF-8) - Usaré un
FileInputStream
/FileOutputStream
para realizar operaciones sobre archivos.
close()
.También estás operaciones suelen declarar varias excepciones (cuando no existe un fichero, no se tiene acceso, hay una codificación desconocida... cualquier error de entrada y salida). Esto hace que deban estar rodeadas de la cláusula
try-catch
para controlarlas.No obstante, como
BufferedReader
/Writer
implementan la interfaz AutoCloseable
, voy a usar un try-with-resources
para que se encargue automáticamente de cerrarme el fichero cuando acabe de usar mi Reader
/Writer
.El código para la lectura queda:
public static String leer (String ruta) {
String leido = "";
try (BufferedReader buffer = new BufferedReader(
new InputStreamReader(
new FileInputStream(ruta), "UTF-8"))) {
String linea;
while((linea = buffer.readLine()) != null) {
leido += linea + System.lineSeparator(); //Esto variará
}
} catch (Exception e) {
e.printStackTrace();
}
return leido;
}
Para la escritura:public static void escribir (String texto, String ruta) {
try (BufferedWriter buffer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(ruta), "UTF-8"))) {
buffer.write(texto); //Esto variará
} catch (Exception e) {
e.printStackTrace();
}
}
Nota: Si queremos guardar en varias lineas es mejor usar el método
buffer.newLine()
antes que usar la secuencia de escape "\n
", pues hará el salto de línea correcto independientemente del SO donde se esté ejecutando (no es igual para Linux (\r\n
) que para Windows (\n
))He encapsulado el código en métodos estáticos para que quede más claro el código para leer y el código para escribir.
Con esta sintaxis tienes optimizada la escritura de texto en ficheros y puedes elegir la codificación
Para practicar con una ruta relativa con un directorio, nos tenemos que crear una nueva carpeta en nuestro proyecto (
New > Folder
) que llamaremos datos
. Cuando ejecutemos el código de abajo y refresquemos el proyecto (Refresh F5
), nuestro fichero aparecerá dentro de ella con el nombre miTexto.txt
.Vamos a ejecutarlo con un ejemplo sencillo en nuestro
main
:String ruta = "datos\\miTexto.txt";
String texto = "Primera linea.\nSegunda Linea.";
System.out.println("Guardo:\n" + texto);
escribir(texto, ruta);
String textoLeido = leer(ruta);
System.out.println("\nLeido:\n" + textoLeido);
De esta forma vemos que nuestro texto se guardo en disco y se ha leído devolviendo el mismo resultado.Evidentemente no todo será guardar una cadena de texto formada y devolver un texto leído, pero con este ejemplo se ve la estructura básica en un ejemplo sencillo. Luego tocará cambiar la linea marcada con el comentario "
Esto variara
" con lo que haya que hacer al leer cada línea o al tener que guardar varias lineas distintas por ejemplo al guardar elementos de una colección.La primera vez puede parecer complejo ver cómo se instancia nuestro
buffer
(es normal, le pasa a todo el mundo). Usándolo más veces al final todo tiene sentido, pero se soluciona fácilmente guardando el enlace donde se ve la sintaxis o simplemente haciéndonos nuestros propios métodos que encapsulen este código.
Buenas tardes, solo comentar que para que funcione la creación de ficheros, en mi caso he tenido que importar la siguiente librería:
ResponderEliminarimport java.io.BufferedWriter;
Efectivamente cuando usas clases que no están en el paquete hay que importarlas. Normalmente al usar el asistente de contenido te lo importa en automático. Si no te saldrá un error y la ayuda te ofrecerá esa solución.
EliminarLa verdad que no está puesto en esta entrada porque en este punto del curso ya se ha tenido que hacer en otros ejemplos. Espero que no te haya hecho perder demasiado el tiempo.
Un saludo.
Quería copiar estas:
ResponderEliminarimport java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.FileOutputStream;
import java.io.FileInputStream;
¡Correcto! Hacen falta todas esas para el ejemplo.
Eliminar