Contenido del curso
Pensando en objetos
Construcción de clases y modelado de objetos
- 10

Métodos estáticos para clases utilitarias en Java
08:43 min - 11

Constantes en Java: inmutabilidad con static final
04:08 min - 12

Constructores en Java para objetos con datos
08:10 min - 13

Gestión de memoria en Java: stack, heap y garbage collector
07:04 min - 14

Encapsulamiento en Java: Atributos privados y métodos getter y setter
09:26 min - 15

Listas en Java: agregar, recorrer y eliminar
11:12 min - 16

Asociación, agregación y composición en Java
03:45 min - 17

Menú interactivo en Java con switch
11:37 min - 18

Buscar y eliminar películas en Java
09:20 min
Estructuras de datos y Java moderno
- 19

Streams y lambdas para filtrar listas en Java
11:55 min - 20

Ordenar y transformar listas con streams en Java
11:49 min - 21

Validación de entrada con enums en Java
11:56 min - 22

Excepciones personalizadas en Java
08:16 min - 23

Records para simplificar código inmutable en Java
06:59 min - 24

Mapas en Java para contar visualizaciones de películas
09:47 min - 25

Leer archivos planos con Java nio
Viendo ahora - 26

Escribir en archivos planos con Files.writeString
09:50 min
Reutilización y diseño orientado a objetos
Leer archivos planos con Java nio
Resumen
Leer archivos planos en Java es una de las habilidades base que necesitas como desarrollador para que tus aplicaciones recuperen información incluso después de reiniciarse. Aquí aprenderás a transformar líneas de texto en objetos usando Files, Paths y un manejo limpio de excepciones, aplicado al caso de Platzi Play y su catálogo de películas.
¿Cómo se estructura un archivo plano para almacenar objetos?
Antes de tocar código, necesitas un archivo de texto bien formado que represente cada objeto como una línea con campos separados por un carácter consistente.
En la raíz del proyecto, hermano de src y de .gitignore, se crea un archivo llamado contenido.txt. Cada línea representa una película y los campos van separados por un pipe (|): título, duración, categoría, calificación y fecha de estreno [01:00].
¿Por qué usar pipe como separador en archivos planos? Porque es un carácter poco común dentro de títulos o textos, lo que reduce el riesgo de partir mal una línea. Comas o puntos suelen aparecer en los datos y rompen el parseo.
Un detalle interesante: algunas películas como Shrek no tienen calificación, así que su campo queda vacío y aparece un doble separador ||. Eso es válido y tu código debe contemplarlo.
¿Cómo leer un archivo plano línea por línea en Java?
Java ofrece desde el paquete java.nio.file dos clases que hacen esta tarea muy sencilla: Files y Paths.
El método Files.readAllLines retorna una List<String> con cada línea del archivo. Para indicarle la ruta usas Paths.get("contenido.txt"). El resultado es una lista que puedes recorrer con un forEach.
java try { List<String> lineas = Files.readAllLines(Paths.get("contenido.txt")); lineas.forEach(linea -> System.out.println(linea)); } catch (IOException e) { System.out.println("Ocurrió un error leyendo el archivo: " + e.getMessage()); }
¿Por qué Java obliga a manejar IOException al leer archivos?
Porque IOException es una checked exception: representa errores previsibles, como que el archivo no exista o no se pueda abrir, y Java te fuerza a controlarlos con try/catch o declarándolos con throws [02:30].
Envolver la lectura en un bloque try/catch te permite mostrar un mensaje útil al usuario en lugar de que la aplicación se caiga sin explicación.
¿Cómo convertir cada línea de texto en un objeto Película?
Leer las líneas es solo el primer paso. Lo valioso es transformar ese texto plano en objetos que tu aplicación pueda usar.
Dentro del forEach, cada línea se parte usando split con la expresión regular \\|. El doble backslash es necesario para escapar el carácter especial pipe en regex. El resultado es un arreglo de strings llamado datos.
java String[] datos = linea.split("\|"); if (datos.length == 5) { String titulo = datos[0]; int duracion = Integer.parseInt(datos[1]); Genero genero = Genero.valueOf(datos[2].toUpperCase()); double calificacion = datos[3].isBlank() ? 0 : Double.parseDouble(datos[3]); LocalDate fechaEstreno = LocalDate.parse(datos[4]); }
Aquí ocurren varias cosas importantes:
- La validación
datos.length == 5descarta líneas mal formadas. Integer.parseIntyDouble.parseDoubleconvierten texto a tipos numéricos.Genero.valueOfmapea el texto a un valor del enum, por eso se pasa a mayúsculas.LocalDate.parseconvierte el texto en un objeto de fecha sin librerías externas.
¿Cuál es la diferencia entre isBlank e isEmpty en Java?
isEmptysolo verifica si el string tiene longitud cero.isBlankademás detecta cadenas que solo contienen espacios en blanco, lo que lo hace más seguro para validar datos sucios.
La expresión datos[3].isBlank() ? 0 : Double.parseDouble(datos[3]) es un operador ternario: una forma compacta de escribir un if/else dentro de una asignación.
¿Cómo organizar la lectura de archivos siguiendo buenas prácticas?
Tener todo este código dentro del main funciona, pero ensucia tu clase principal. La buena práctica es centralizarlo en una clase de utilidades.
Dentro del paquete util se crea una clase FileUtils con un método estático leerContenido que retorna una List<Pelicula>. También se extraen dos constantes para evitar valores mágicos en el código:
NOMBRE_ARCHIVOcon el valor"contenido.txt".SEPARADORcon el valor"\\|".
java public static List<Pelicula> leerContenido() { List<Pelicula> contenidoDesdeArchivo = new ArrayList<>(); try { List<String> lineas = Files.readAllLines(Paths.get(NOMBRE_ARCHIVO)); // parseo y add a la lista } catch (IOException e) { System.out.println("Error: " + e.getMessage()); } return contenidoDesdeArchivo; }
En el main, cargar las películas se reduce a una sola línea: plataforma.getContenido().addAll(FileUtils.leerContenido()). El método addAll recibe una colección completa y la integra a la lista existente.
¿Qué ganas al persistir datos en archivos planos?
La aplicación recupera su estado al iniciar. Si reordenas las líneas en contenido.txt y pones Titanic primero, al ejecutar la opción de mostrar todo, Titanic aparece de primero. Eso confirma que los datos vienen del archivo y no de un hardcode en el código fuente.
Este mismo patrón te sirve para catálogos, configuraciones, logs o cualquier información que necesites mantener entre ejecuciones. ¿Qué archivo plano vas a leer en tu próximo proyecto? Cuéntalo en los comentarios.