1. Gestión de ficheros en Java
Cuando accedemos a un fichero desde Java este delega luego en el sistema operativo (este comprueba que el fichero no esté ya abierto por otro proceso, permisos, etc.). Si todo está correcto obtenemos los metadatos del fichero.
En Java existen varios paquetes para gestión de ficheros:
- java.io: File, InputStream, FileInputStream, OutputStream, FileOutputStream, Reader, FileReader, Writer, FileWriter, BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream...
- java.nio: Buffer, Channel
- java.nio.2: Path (interfaz), Files, FileSystem, FileSystems, Paths. Paths y Files contiene solamente métodos estáticos que retornan objetos de tipo "Path" (Path es una interfaz).
1.1 Clase File
1.1.1 Creando un fichero
String filename = "ficheros/test.csv";
File f = new File(filename);
boolean createdSuccessfully = f.createNewFile(); // (1)!
System.out.println(createdSuccessfully ?
"Fichero creado con éxito." :
"No se ha podido crear el fichero."
);
- Falta la captura de excepciones. Por limpieza del código se omitirán en la mayoría de casos.
Ejercicio
- Añade la captura de excepciones necesarias a l programa anterior.
- Revisa en qué ruta se ha creado el fichero y por qué.
- Comprueba qué ocurre si pones delante de la ruta una "/".
Vamos ahora a cargar un fichero del sistema e imprimir la ruta donde se encuentra:
La clase File tiene un método para comprobar si el fichero existe:
private static void printPath(String path) {
File f = new File(path);
if (f.exists()) {
System.out.println(f.getAbsolutePath());
} else {
System.out.println("El fichero no existe.");
}
}
1.1.2 Comprobando la raíz de sistema
La raíz es distinta en Windows (C/D/E...) y GNU/Linux (/). Podemos usar lo siguiente para ver la raíz (o las raices del sistema):
private static void printAllSystemRoots() {
for (File f : File.listRoots()) {
System.out.println(f);
}
}
public static void main(String[] args) {
printAllSystemRoots();
}
Podemos usar también la Stream API de Java e imprimirlas con un foreach:
1.1.3 Otros métodos de File
Algunos de los más interesantes son los siguientes:
| Retorno | Método |
|---|---|
| boolean | canRead() |
| boolean | canWrite() |
| boolean | canExecute() |
| boolean | createNewFile() |
| boolean | delete() |
| boolean | exists() |
| boolean | isDirectory() |
| boolean | isFile() |
| boolean | isHidden() |
| boolean | mkdir() |
| File | getAbsolutePath() |
| File | getCanonicalPath() |
| File[] | listFiles() |
Ejercicio
Haz el siguiente ejercicio dos veces: - Primera vez usa los métodos anteriores (java.io). - Segunda vez usa Files + Path (haz los mismos ejercicios con clase Files + Path, es decir, java.nio)
public static void main(String[] args) {
// TODO: Crea una nueva carpeta
// TODO: Crea un nuevo fichero (solo si no existía antes)
// TODO: Lee lo que hay en el fichero
// TODO: Comprobar los permisos que tienes sobre el fichero (puedes escribir en él y leer?)
// TODO: ¿Es un fichero o un directorio?
// TODO: ¿Está oculto?
// TODO: Dame el PATH completo del fichero
// TODO: Lista lo que hay en una carpeta del sistema.
}
1.2 Clase Files (java.nio)
La clase Files sirve más o menos para lo mismo que File, pero en este caso contiene todo métodos estáticos y recibe un Path como parámetro.
No tienes que saberlos de memoria, si quieres realizar alguna operación puedes usar tu IDE o internet para ver como hacerla. También, si quereis ver más información u otros métodos de java.io.File podéis consultar el API de Java.
1.3 Actividad II: java.nio.Files
Completa la siguiente tabla usando solo métodos de java.nio.Files y escribe un programa muy simple que pruebe 5 de ellos y otros 5 distintos que te parezcan interesantes del API de Java).
La dificultad añadida de "Files" es que siempre recibe como parámetro un "Path". Aquí dejo un buen artículo de internet como apoyo.
| Retorno | Método clase File | Método Files/Path |
|---|---|---|
| boolean | canRead() | - |
| boolean | canWrite() | - |
| boolean | canExecute() | - |
| boolean | createNewFile() | - |
| boolean | delete() | - |
| boolean | exists() | - |
| boolean | isDirectory() | - |
| boolean | isFile() | - |
| boolean | isHidden() | - |
| boolean | mkdir() | - |
| File | getAbsolutePath() | - |
| File | getCanonicalPath() | - |
| File[] | listFiles() | - |
1.4 Actividad III: navegador de archivos sencillo
Crea un navegador de archivos simple en la consola de Java (mediante un menú) que permita realizar las siguientes operaciones:
1.4.1 Arranque del programa
Cuando inicias el programa se guardará la ruta actual y mostrará:
- La ruta absoluta actual.
- La lista de archivos y carpetas existentes en la ruta.
1.4.2 Listar ficheros
Si escribes la palabra "ls" se mostrará la lista de archivos en la carpeta actual.
1.4.3 Lectura de un fichero o directorio
Si se introduce la palabra "cd" y una ruta absoluta pueden pasar dos cosas:
- En caso de corresponder a un directorio se mostrarán los archivos y directorios contenidos en él.
- En caso de corresponder a un fichero se mostrará su contenido.
1.4.4 Leer el principio de un fichero
Si se introduce la palabra "head" se preguntará un nombre de fichero, en caso de existir se mostrarán las 10 primeras líneas (en caso contrario se indicará que no existe).
1.4.5 Crear un directorio
Si se escribe "mkdir" se debe preguntar al usuario el nombre del directorio y la ruta donde se desea crear.
1.4.6 Crear un fichero (con contenido)
Si se escribe "file" se pregunta al usuario el nombre del fichero y la ruta donde se desea crear. Si esto es válido pregúntale al usuario que contenido desea añadir al mismo.
1.4.7 Añadir contenido a un fichero
Si se escribe "add-text" preguntarás al usuario la ruta del fichero y el texto que quiere añadirse. Se añadirá después del último carácter que haya escrito en el fichero.
1.4.8 Eliminar un fichero o directorio
Si se escribe "rm" pide una ruta y se elimina el fichero o directorio correspondiente a la misma.
1.4.9 Salir del programa
Si se escribe "salir" se termina el programa.
1.5 Actividad IV: XML
Crea un nuevo proyecto con una clase "Mascota" con los atributos:
- id: long
- breed: String
- name: String
- type: String
- color: String
1.5.1 Conversiones entre XML y objetos Java
Crea una clase "Principal" con un método "main" y crea un objeto Mascota. Después, conviértelo a XML de manera que consigas una salida como esta por consola:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pet id="1">
<nombre>Darwin</nombre>
<tipo>gato</tipo>
<raza>Siamés</raza>
<color>gris</color>
</pet>
- Haz que el XML anterior se almacene en un fichero en vez de por salida estándar (stdout).
- Obtén el XML almacenado en el fichero y conviértelo en un objeto Mascota.
1.5.2 Organización de código y uso de genéricos
Organiza el código en clases de manera que tengas:
- Una clase ConversorJaxbDeObjetoAXml con métodos que reciban objetos mascota y realicen lo siguiente:
- Almacenar mascota en fichero.
- Mostrar por salida estándar (consola).
- Una clase ConversorJaxbDeXmlAObjeto con métodos que reciban un XML y realicen lo siguiente:
- Obtener objeto de fichero.
- Haz que el código utilizado sirva para cualquier otra clase (no solo para Mascota). Para esto necesitas utilizar genéricos.
1.6 Actividad V: Manipulación de JSON
1.6.1 Conversión entre JSON y objetos Java
Crea un nuevo proyecto con una clase mascota con los atributos:
- id: long
- breed: String
- name: String
- type: String
- color: String
Crea una clase "Principal" con un método "main" y crea un objeto Mascota. Después, conviértelo a JSON utilizando GSON o Jackson de manera que consigas una salida como esta por consola:
{
"mascota" : {
"id" : 1,
"nombre" : "Darwin",
"tipo" : "gato",
"raza" : "Siamés",
"color" : "gris"
}
}
Finalmente, cambia el nombre de la mascota y realiza la transformación inversa (convierte el json generado a un objeto "Mascota" nuevamente).
1.6.2 Organización de código y uso de genéricos
Crea una interfaz ConversorORMJson con las definiciones de los siguientes métodos: 1. aObjeto(String json): Mascota 2. aJson(Mascota m): String
Posteriormente, crea una clase ConversorORMGson o ConversorORMJackson (según qué biblioteca estés usando) que implemente la interfaz anterior.
Haz que la interfaz y las clases anteriores sirvan para cualquier tipo de entidad (utiliza genéricos).
1.7 Actividad VI: Visualización de datos COVID
1.7.1 Contexto
En 2020, Daniel González Peña, profesor la escuela superior de ingeniería informática en Ourense realizó una recopilación, día a día, de los datos de la incidencia del COVID en Galicia y los centralizó en un repositorio de GitHub.
Descarga el fichero CSV con la incidencia del COVID en centros educativos ordenados por fecha disponible aquí.
1.7.2 Visualización en consola
Crea una aplicación en dos capas (dos paquetes, iu y datos), donde las clases de la capa de IU se ocupen de mostrar un menú para las siguientes opciones:
- Obtener todos los datos ordenados por el nombre del centro educativo.
- Obtener todos los datos de un solo día indicado (el día será 1, 2, 3...). Tendrás que agruparlos.
- Obtener datos por ayuntamiento y fecha (se pedirá ayuntamiento, día, mes y año, numéricos).
- Obtener la lista de centros cerrados indicando el número de casos activos y la fecha.
Todas las operaciones de ese menú tendrán que realizarse con funciones en la capa de datos (en este ejercicio solo usaremos una clase a la que vamos a llamar DatosCovidDao). Ahí tendrás que realizar todas las operaciones.
1.7.3 Visualización en web dinámica
Crea una aplicación en Java que cargue el CSV en memoria con cada petición GET a /datoscovid con las siguientes operaciones:
- /datoscovid/all: Obtener todos los datos ordenados por el nombre del centro educativo.
- /datoscovid/all?page={dia}: Obtiene los datos del primer día disponible (si se pasa en dia un 1), si se pasa un 2 será el segundo día, etc.
- /datoscovid/all?centro={nombre}: Obtiene los datos históricos del centro educativo, si existe.
- /datoscovid/all?ayuntamiento={nombre}: Obtener datos por ayuntamiento.
- /datoscovid/all?cerrado=1 (o cerrado=0): Obtener la lista de centros cerrados.
Puedes aprovechar la capa de datos anterior.
1.8 TODOs futuros (mejoras)
- Separar completamente ejercicios que usan java.io y java.nio. Intentar buscar buen contenido externo que enlazar sobre esto, ya que es enrevesado (o simplemente restarle importancia).
- Más ejemplos con java.nio y java.nio2
- Optimizar o reducir la parte de XML. Pensar en dar opción entre librerías (JAXB y XStream)
- Un posible inicio de proyecto.
- Buenas referencias externas para crear una webs dinámicas en Java. Tomcat.