Ficheros de caracteres¶

Las clases Java FileWriter y FileReader se utilizan para escribir y leer datos de archivos de texto (son clases de flujo de caracteres, character stream). Se recomienda no utilizar las clases FileInputStream y FileOutputStream si vamos a leer o escribir información de texto.
| Extensión | Tipo de fichero |
|---|---|
| .txt | Fichero de texto plano |
| .xml | Fichero XML |
| .json | Fichero de intercambio de información |
| .props | Fichero de propiedades |
| .conf | Fichero de configuración |
| .sql | Script SQL |
| .srt | Fichero de subtítulo |
Escritura de caracteres¶
La clase Java FileWriter del paquete java.io se utiliza para escribir datos en forma de caracteres en un archivo.
- Esta clase hereda de la clase
OutputStream. - Los constructores de esta clase asumen que la codificación de caracteres predeterminada y el tamaño de búfer de bytes predeterminado son aceptables.
FileWriterestá diseñado para escribir secuencias de caracteres. Si queremos escribir flujos de bytes sin procesar, tendríamos que usar la claseFileOutputStream.
Los métodos principales
| Método | Descripción |
|---|---|
| void write(int caracter) | escribe un carácter en el archivo |
| void write(String cadena) | escribe una cadena en el archivo |
| void newline() | escribe un salto de línea en el fichero. Se debe evitar el uso explícito del carácter \n para insertar saltos de línea, ya que su codificación es distinta según la plataforma utilizada. |
| void flush() | vacía el buffer de salida, escribiendo en el fichero los caracteres pendientes. |
| void close() | cierra el flujo de salida, vaciando el buffer y liberando el recurso correspondiente. |
Cuando trabajamos con flujos es necesario cerrarlo para evitar perdida de recursos, incluso aunque se produzca un error, por lo que normalmente se realiza en el el apartado finally del try/cath.
Warning
Siempre hay que cerrar el flujo para asegurarse de liberar todos los recursos asociados a él y que el sistema operativo no consuma recursos.
La excepción IOException se lanza si el stream se ha cerrado y el flujo de salida contenido no admite la escritura después del cierre, o se produce otro error de I/O.
try-with-resources¶
La declaración try-with-resource es una característica introducida en Java 7 que facilita la gestión de recursos que deben cerrarse explícitamente, como flujos de archivos o conexiones a bases de datos. Permite que los recursos sean automáticamente cerrados una vez que el bloque try termina, incluso si ocurre una excepción. Esto simplifica el código y reduce la posibilidad de fugas de recursos.
public static void main(String[] args) {
try(DataOutputStream fos = new DataOutputStream(new FileOutputStream("datos.dat"))) {
fos.writeInt(0);
fos.writeInt(-34);
} catch (FileNotFoundException e) { //todas pueden derivar de IOException
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
finally
Vamos a ver un ejemplo para flujo de caracteres
/**
* Escribe texto en un fichero llamado "output.txt"
* utilizando BufferedWriter y try-with-resources.
*
* El fichero se crea automáticamente si no existe.
* Si existe, se sobrescribe.
*/
public static void main(String[] args) {
// try-with-resources:
// BufferedWriter se cerrará automáticamente al finalizar el bloque
try (BufferedWriter fw =
new BufferedWriter( // Añade buffer (mejora rendimiento)
new FileWriter("output.txt"))) { // Conexión al fichero
// Escribimos una línea de texto
fw.write("Esto es un ejemplo");
// Insertamos salto de línea (equivalente a \n pero portable)
fw.newLine();
// Escribimos segunda línea
fw.write("Segunda linea");
// No es necesario llamar a close()
// Se cerrará automáticamente
} catch (IOException e) {
// Captura errores de entrada/salida
System.out.println("Error E/S: " + e);
}
}
public static void main(String[] args) {
BufferedWriter fw=null;
try {
fw =new BufferedWriter(new FileWriter("output.txt"));
fw.write("Esto es un ejemplo");
//nueva linea
fw.newLine();
fw.write("Segunda linea");
} catch(IOException e) {
System.out.println("Error E/S: " + e);
}finally{
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Cuando se cierra el stream close() se escribe en el fichero.
En el caso de try/resouce no es necesario llamar a close() ya que lo hace de forma automática.
Si quisiéramos grabar en el fichero en algún momento antes de cerrar, podemos usar el método flush().
fw.write("Esto es un ejemplo");
fw.flush();
Escritura de String como System.out¶
Podemos utilizar la clase PrintWriter para la escritura de String en el archivo. Proporciona métodos parececidos a System.out
public static void main(String[] args) {
try (
FileWriter fileWriter = new FileWriter("output.txt");
PrintWriter printWriter = new PrintWriter(fileWriter);
) {
// Datos
String nombre = "Juan";
int edad = 30;
double altura = 1.75;
// ====== CABECERA ======
// %-10s → String alineado a la izquierda en 10 espacios
// %10s → alineado a la derecha en 10 espacios
printWriter.printf("%-10s %-10s %-10s\n",
"Nombre", "Edad", "Altura");
// Línea separadora
printWriter.println("--------------------------------");
// ====== DATOS ======
printWriter.printf("%-10s %-10d %-10.2f\n",
nombre, edad, altura);
System.out.println("Se ha escrito en el archivo exitosamente.");
} catch (Exception e) {
e.printStackTrace();
}
}
Lectura de datos¶
Carácter a carácter: FileReader¶
FileReader es una clase en el paquete java.io que se usa para leer una secuencia de caracteres de los ficheros. Esta clase se hereda de la clase InputStreamReader.
FileReaderestá diseñada para leer flujos de caracteres. Para leer flujos de bytes sin procesar, usaremosFileInputStream.
Los métodos principales
| Método | Descripción |
|---|---|
| readLine() | para leer líneas de texto del fichero (String). Este método devuelve null cuando no hay más líneas para leer |
| read() | para leer carácter a carácter. Devuelve un entero que representa el código Unicode del carácter leído. Devuelve -1 si no hay más caracteres. |
/**
* Lee el fichero "output.txt" carácter a carácter
* y muestra su contenido por pantalla.
*
* Utiliza:
* - FileReader → para leer caracteres (fichero de texto)
* - try-with-resources → para cerrar automáticamente el flujo
*/
public static void main(String[] args) {
// Variable donde almacenaremos el carácter leído
int ch;
// try-with-resources:
// FileReader se cerrará automáticamente al salir del bloque
try (FileReader fr = new FileReader("output.txt")) {
// Leemos el primer carácter del fichero
// read() devuelve:
// - un entero (código ASCII/Unicode del carácter)
// - -1 cuando llega al final del fichero
ch = fr.read();
// Mientras no sea fin de fichero (-1)
while (ch != -1) {
// Convertimos el entero a carácter
// y lo mostramos por pantalla
System.out.print((char) ch);
// Leemos el siguiente carácter
ch = fr.read();
}
} catch (IOException fe) {
// Se ejecuta si ocurre algún error de lectura
System.out.println("Error de E/S");
}
}
Línea a línea: BufferedReader¶
Otro ejemplo en el que se leen líneas completas. En este caso utilizamos BufferedReader
/**
* Lee el fichero "datos.txt" línea por línea
* utilizando BufferedReader.
*
* - Usa try-with-resources → cierre automático
* - Lee con readLine()
* - Muestra cada línea por pantalla
*/
public static void main(String[] args) {
// try-with-resources:
// El BufferedReader se cerrará automáticamente al finalizar el bloque
try (
BufferedReader in = new BufferedReader(
new FileReader("datos.txt"))
) {
// Leemos la primera línea del fichero
// readLine() devuelve:
// - Un String con la línea
// - null si llega al final del fichero
String cadena = in.readLine();
// Mientras no sea fin de fichero
while (cadena != null) {
// Mostramos la línea por pantalla
System.out.println(cadena);
// Leemos la siguiente línea
cadena = in.readLine();
}
} catch (FileNotFoundException e) {
// Se ejecuta si el fichero no existe
System.out.println("ERROR. Archivo no encontrado");
} catch (IOException e) {
// Se ejecuta si ocurre error de lectura
System.out.println(e.getMessage());
}
}
Lectura de ficheros de texto con Scanner¶
A partir de Java 5 se puede leer un fichero de texto utilizando la clase Scanner igual que si
leyéramos por teclado. Para ello se le pasa al constructor de Scanner el objeto FileReader
asociado al fichero. Esta operación lanza una excepción FileNotFoundException.
Lectura de un fichero de texto con una serie de enteros separados por secuencias de espacios y tabuladores, incluso en líneas distintas
12 34 56 32 43
/**
* Método main
*
* Lee números enteros desde el fichero "datos.txt"
* utilizando:
*
* - FileInputStream → abre el fichero
* - Scanner → permite leer números fácilmente
*/
public static void main(String[] args) {
try (
FileInputStream flujo = new FileInputStream("datos.txt"); // conexión con el fichero
var sc = new Scanner(flujo); // lector de tokens (números, texto, etc.)
) {
// Mientras haya datos disponibles en el fichero
// hasNext() devuelve true si hay más tokens
while (sc.hasNext()) {
// Leemos el siguiente número entero
// nextInt() lanza excepción si el dato no es un entero
int n = sc.nextInt();
// Mostramos el número leído
System.out.print(n + " ");
}
} catch (FileNotFoundException e) {
// Se ejecuta si el fichero no existe
System.out.println("ERROR. Archivo no encontrado");
} catch (IOException e) {
// Se ejecuta si ocurre error de entrada/salida
System.out.println("ERROR de E/S");
}
}