Memoria técnica completa del desarrollo de un sistema modular de análisis y optimización de sistemas de archivos. Implementado en Java 17 con programación funcional, hashing criptográfico y gestión avanzada de errores.
¿Por qué construir JDiskCleaner? El punto de partida del proyecto.
La acumulación de archivos temporales, duplicados y datos obsoletos es un problema crítico en sistemas de desarrollo y producción. Los gestores de disco convencionales son cajas negras: el usuario no sabe qué están borrando ni por qué.
Una librería de consola con filosofía auditora: el usuario comprende en todo momento qué acción se está ejecutando, qué archivos se ven afectados y con qué criterio. Transparencia total sobre el sistema de archivos.
Arquitectura en capas con Responsabilidad Única (SRP). Cada clase tiene un único propósito y puede ser reutilizada de forma independiente. El motor DiskService es completamente desacoplado de la UI.
Dominar la API Java NIO.2 para I/O moderno, aplicar la Streams API para procesamiento funcional de datos, y gestionar errores mediante excepciones personalizadas con jerarquías bien definidas.
Estructura en capas desacopladas siguiendo principios SOLID.
Cómo viajan los datos desde el input del usuario hasta el resultado en pantalla.
Explora cada fichero del proyecto con análisis técnico línea a línea.
Desglose técnico de cada operación implementada en el sistema.
| Funcionalidad | Categoría | Implementación Técnica | Clases Involucradas | Impacto |
|---|---|---|---|---|
| Análisis Top-N Archivos Mayores consumidores de espacio |
Diagnóstico | Recorrido recursivo con Files.walk(). Pipeline de Stream con filter → map → sorted(reversed) → limit(N). |
DiskService, FileStats |
Identificación de archivos pesados sin explorar manualmente. |
| Detección de Duplicados Comparación por contenido binario |
Avanzado | Cálculo de hash MD5 con MessageDigest. Agrupación con Collectors.groupingBy(hash). Solo los grupos con size() > 1 son duplicados reales. |
FileUtil, DiskService, DuplicateGroup |
Ahorro de espacio real basado en contenido, no en nombres. |
| Limpieza de Temporales Extensiones: .tmp, .log, .bak, .cache |
Limpieza | Filtros de extensión dinámicos con String.endsWith() en predicados de Stream. Eliminación con Files.delete() precedida de confirmación. |
DiskService, FileUtil |
Optimización rápida del disco con mínimo riesgo. |
| Organizador por Extensión Carpetas: Images, Docs, Videos... |
Organización | Detección de extensión con Path.getFileName(). Creación dinámica de carpetas con Files.createDirectories(). Movimiento con Files.move(). |
DiskService, FileOrganizer |
Estructura de directorios limpia y auto-gestionada. |
| Reporte de Espacio Resumen de uso por directorio |
Diagnóstico | Suma acumulada de bytes con Stream.mapToLong().sum(). Formateo de unidades (B/KB/MB/GB) con lógica condicional encadenada. |
DiskService, FileUtil |
Visión general del estado del disco instantánea. |
| Búsqueda por Patrón Glob patterns y wildcards |
Avanzado | Uso de FileSystem.getPathMatcher() con sintaxis glob. Pipeline de Stream con filter(matcher::matches). |
DiskService, FileUtil |
Localización precisa de archivos por patrones complejos. |
| Archivos por Antigüedad Filtro por fecha de último acceso |
Limpieza | Lectura de BasicFileAttributes con Files.readAttributes(). Comparación de FileTime con umbral configurable. |
DiskService, FileStats |
Eliminación segura de archivos inactivos. |
| Exportar Informe Salida en formato .txt estructurado |
Utilidad | Escritura con Files.write() y StandardOpenOption.CREATE. Construcción del contenido con StringBuilder y formateo de fechas con LocalDateTime. |
DiskService, FileUtil |
Trazabilidad completa de todas las operaciones realizadas. |
Los pilares técnicos del proyecto explicados didácticamente.
Los Streams permiten procesar colecciones de datos de forma declarativa, sin bucles explícitos. Se componen de operaciones intermedias (filter, map, sorted) y terminales (collect, toList). Son lazy: no se evalúan hasta la operación terminal.
La API de I/O moderna de Java (desde Java 7). Reemplaza a java.io.File con java.nio.file.Path. Ofrece Files.walk() para recorrido recursivo, Files.readAttributes() para metadatos, y Files.move/delete/copy para operaciones atómicas.
Para detectar duplicados reales (no por nombre), se calcula el hash MD5 de cada archivo. Dos archivos con el mismo hash tienen contenido idéntico con probabilidad criptográfica. Se usa MessageDigest de java.security.
Los Records son clases de datos inmutables con sintaxis concisa. El compilador genera automáticamente constructor, getters, equals(), hashCode() y toString(). Perfectos para transportar resultados de análisis sin riesgo de mutación accidental.
En lugar de propagar genéricas IOException, JDiskCleaner usa una jerarquía propia. DiskException extiende Exception y diferencia fallos de acceso de errores lógicos. Esto permite catch específicos y mensajes de error claros para el usuario.
Los Streams de NIO.2 como el que devuelve Files.walk() implementan AutoCloseable. Usarlos en un bloque try(Stream<Path> s = Files.walk(...)) garantiza que el stream se cierra automáticamente, evitando file handle leaks.
Proceso iterativo desde el esqueleto hasta la versión funcional.
ui, service, util, model, exception). Definición de contratos entre capas. Primer esqueleto de Main.java con menú básico.Files.walk() con manejo de permisos. Construcción del pipeline de Streams para el análisis Top-N. Definición del Record FileStats.DiskException y jerarquía de errores. Mejora del formateo de salida con colores ANSI. Exportación de informes en texto. Pruebas en directorios reales.Una evaluación honesta de las fortalezas y limitaciones del sistema.
parallelStream() en cores múltiples.Implementar Files.walkFileTree() con un SimpleFileVisitor personalizado para mayor control de acceso. Añadir parallel streams para discos SSD con múltiples cores. Migrar la UI a JavaFX con gráficas de uso de disco. Implementar un caché con ObjectOutputStream para evitar re-escaneos completos.
Transparencia total sobre el uso de herramientas de inteligencia artificial.
MessageDigest y la forma correcta de convertir el array de bytes a hexadecimal.Todo el código generado o sugerido por IA ha sido: