7.4.1.-Archivo de texto
7.4.1 Ficheros de texto¶
En 7.4 vimos la visión general de la lectura y escritura de archivos. En esta ampliación nos centramos en el caso más habitual en el aula: los ficheros de texto.
Trabajar con texto es muy común porque permite guardar información de forma sencilla, visible y fácil de depurar. Además, es ideal para practicar cómo leer, escribir y procesar datos persistentes en programas pequeños y medianos.
Qué vas a aprender en este apartado
- Cuándo conviene usar un fichero de texto.
- Cómo leer un fichero completo o línea a línea.
- Cómo escribir texto sobrescribiendo o añadiendo contenido.
- Cómo influyen caracteres como
\n,\ry\t.
1. Qué es un fichero de texto¶
Un fichero de texto almacena la información como caracteres. Eso hace que, en muchos casos, podamos abrirlo con un editor y entender su contenido directamente.
Ejemplos típicos:
- configuraciones;
- listados de datos;
- archivos CSV;
- informes;
- registros de eventos.
Ventaja principal
Los ficheros de texto son muy cómodos para aprender, porque permiten ver de forma directa qué se ha guardado realmente.
2. Crear una referencia al fichero¶
Antes de leer o escribir, necesitamos una referencia al fichero mediante File:
Esto no lee todavía el contenido. Solo prepara la ruta con la que vamos a trabajar.
3. Leer ficheros de texto¶
Kotlin ofrece varias formas de leer ficheros de texto. La elección depende de cuánto contenido quieras leer y de cómo vayas a procesarlo.
3.1. Leer todo con readText()¶
Si el fichero es pequeño o mediano, readText() resulta muy cómodo:
import java.io.File
fun main() {
val contenido = File("datos/notas.txt").readText()
println(contenido)
}
Úsalo cuando necesites el contenido completo como una única cadena.
3.2. Leer todas las líneas con readLines()¶
Si te interesa trabajar por líneas, readLines() devuelve una lista:
import java.io.File
fun main() {
val lineas = File("datos/notas.txt").readLines()
for (linea in lineas) {
println(linea)
}
}
Esta opción es práctica cuando el fichero no es enorme y quieres recorrerlo después con comodidad.
3.3. Procesar línea a línea con useLines()¶
Si el fichero puede crecer mucho, useLines() permite procesar el contenido de forma más eficiente:
import java.io.File
fun main() {
File("datos/notas.txt").useLines { lineas ->
lineas.forEach { println(it) }
}
}
Con useLines() no necesitas cargar todo el fichero a memoria a la vez.
Elección rápida
readText()para obtener una sola cadena.readLines()para trabajar con una lista de líneas.useLines()para ficheros grandes o procesamiento secuencial.
4. Escribir en ficheros de texto¶
La escritura también puede hacerse de distintas formas según lo que necesites.
4.1. Sobrescribir con writeText()¶
writeText() escribe texto en el fichero y reemplaza el contenido anterior si ya existía:
Es útil cuando quieres generar el fichero desde cero o rehacerlo completamente.
4.2. Añadir con appendText()¶
Si quieres conservar lo anterior y escribir al final, usa appendText():
Esto es muy útil para historiales, registros o acumulación de resultados.
4.3. Escribir con bufferedWriter()¶
Otra opción es usar un escritor con buffer:
import java.io.File
fun main() {
File("salida.txt").bufferedWriter().use { writer ->
writer.write("Primera línea\n")
writer.write("Segunda línea\n")
}
}
Aquí aparece use(), que garantiza que el recurso se cierre correctamente al terminar.
Muy importante
writeText() borra el contenido anterior. Si necesitas conservar lo ya escrito, usa appendText().
5. Leer y escribir con el mismo formato¶
Cuando un programa escribe información en un fichero de texto, debe hacerlo siguiendo un formato claro. Después, al leer ese fichero, hay que respetar ese mismo formato.
Por ejemplo, si decides guardar cada alumno así:
al leer tendrás que tener presente que:
- cada línea representa un alumno;
- el separador es la coma;
- el primer dato es el nombre;
- el segundo dato es la nota.
Si cambias el formato al escribir y no ajustas la lectura, el programa fallará o interpretará mal los datos.
6. Caracteres especiales importantes¶
En los ficheros de texto aparecen caracteres que no siempre se ven de forma explícita, pero que afectan mucho al resultado.
6.1. Salto de línea \n¶
Sirve para empezar una nueva línea:
6.2. Retorno de carro \r¶
En sistemas Windows suele combinarse con \n para formar \r\n.
6.3. Tabulador \t¶
Permite alinear texto en columnas sencillas:
6.4. Fin de fichero¶
Cuando lees un fichero secuencialmente, llega un momento en que no quedan más datos. A eso se le llama fin de fichero o EOF.
Por eso, al leer línea a línea, conviene usar mecanismos que sepan detenerse correctamente, como useLines() o un bucle que controle el final de lectura.
7. Ejemplos prácticos¶
7.1. Contar líneas¶
import java.io.File
fun main() {
val numeroDeLineas = File("datos/notas.txt").useLines { it.count() }
println("El fichero tiene $numeroDeLineas líneas.")
}
7.2. Registro de eventos¶
import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
fun registrarEvento(evento: String) {
val marcaTiempo = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
File("registro.txt").appendText("[$marcaTiempo] $evento\n")
}
fun main() {
registrarEvento("Inicio de la aplicación")
registrarEvento("Operación completada")
}
7.3. Leer y mostrar un pequeño informe¶
import java.io.File
fun main() {
val informe = File("informe.txt")
if (!informe.exists()) {
println("El fichero no existe.")
return
}
println("Contenido del informe:")
println(informe.readText())
}
8. Buenas prácticas¶
Cuando trabajes con ficheros de texto, intenta seguir estas ideas:
- comprueba si el fichero existe antes de leerlo, cuando tenga sentido hacerlo;
- usa rutas relativas si el proyecto va a moverse entre equipos;
- diferencia claramente entre sobrescribir y añadir contenido;
- usa
use()cuando trabajes con lectores o escritores explícitos; - no cargues en memoria ficheros enormes si puedes procesarlos por líneas;
- y define un formato claro si luego vas a volver a leer el fichero.
Consejo didáctico
Si estás empezando, piensa siempre en dos preguntas: “¿cómo voy a guardar esto?” y “¿cómo lo recuperaré después?”.
9. Errores frecuentes¶
- leer un fichero que no existe;
- usar
writeText()cuando querías añadir y no sobrescribir; - no incluir saltos de línea y dejar todos los datos pegados;
- suponer que el contenido siempre tendrá el formato esperado;
- usar
readText()con ficheros demasiado grandes sin necesidad.
10. Resumen¶
En este apartado has visto que:
- los ficheros de texto son muy útiles para almacenar información legible;
- Kotlin ofrece varias formas cómodas de leerlos y escribirlos;
readText(),readLines()yuseLines()responden a necesidades distintas;writeText()sobrescribe yappendText()añade;- y los caracteres especiales como
\no\tinfluyen directamente en el formato final.
Con esto queda cerrada la parte de trabajo básico con ficheros de texto de la unidad.