Está en la página 1de 62

3.

Ficheros y Bases de Datos

• Previo: gestión de memoria


• Ficheros: File y Path (io / nio)
• Gestión de datos en disco
• Ficheros de texto
• Ficheros binarios: Serializable
• Bases de datos

Programación III
¿Qué es la memoria?
En realidad Pero es más fácil verlo como
00000000 byte
00000001 byte
byte
. byte
.
. .
.
.
dato

dato

obj

obj

FFFFFFFF

Programación III
Arrays / contiguidad
¿Dónde array[0]? ¿Y array[n]? ¿Qué necesitamos?
00000000
00000001

.
.
.

Serie de elementos

02a37f14

array
array

FFFFFFFF

Programación III
¿Modificación? Sec. NO
Random SÍ

¿Inserción? Sec. al final


Random NO

¿Borrado? Sec. NO
Random no/marca

¿Dif. tamaño? Sec. SÍ


Programación III Random NO
Memoria interna y externa

Tbytes
milisegundos
Gbytes Persistente
Nanosegundos Necesita I/O
Volátil
Accesible (Random Access)

Programación III
Ficheros secuenciales y random
Similitud entre memoria primaria y secundaria
0000000000
0000000001

.
.
.

Fichero secuencial

0002a37f14

fich
Fichero secuencial / aleatorio

FFFFFFFFFF

Programación III
¿Y una base de datos?
BD = varios ficheros con estructura y relaciones (tablas)
Índices = arrays sobre estructuras aleatorias
Las claves primarias se gestionan ordenadas con índices

Tabla de base de datos

Índice de base de datos

(Si la estructura es aleatoria, vale con un


índice en lugar de una referencia)

Programación III
java.io: clase File
• Objeto inmutable, representa un fichero o carpeta
• Diferente entre SSOO ("\\", "/")
• Algunos métodos:
– getName(), getParent(), getAbsolutePath()
• toURI()
– exists(), isDirectory(), isFile()
– isHidden(), lastModified(), length()
– list( [filtro] ), listFiles( [filtro] )
– renameTo( f ), delete() [no hay copy!]
– mkdir(), mkdirs()
Programación III
File vs Resource
• File:
– Objeto para referencia a fichero (disco/red)
– Sistema físico de ficheros/comunicaciones
– Partiendo de la carpeta de inicio del proyecto
• Puede navegar en absoluto o relativo (..)
• Resource:
– Parte de la estructura de una clase
• Solo navega hacia adelante de ese punto
– Puede acceder a datos empaquetados que carga el
loader (por ej. en ficheros .jar) en memoria
– Usado fundamentalmente en solo lectura

Programación III
java.io: Streams
– Bytes: FileInputStream, FileOutputStream
– Buffer: BufferedInputStream, BufferedOutputStream
• Texto: BufferedReader,
BufferedWriter, PrintStream
• Objetos: ObjectInputStream, ObjectOutputStream
• Acceso directo: RandomAccessFile (seek)
– Binarios: FileInputStream / FileOutputStream ☺
– Puede ser útil ByteBuffer (convierte datos a arrays
de bytes)

Programación III
java.nio (Java 7)
• Se puede copiar y recorrer
– Clase java.nio.files.Files
• copy( fuente, destino, opciones )
• delete, exists, move, create...
• Recorrer: walk, walkFileTree
• Globs (patrones simplificados. Ej: *.html, Pr??.java)
• Monitorización de cambios en ficheros/carpetas
– (ver MonitorizaDisco.java)
• Path para mejorar File:

Programación III http://docs.oracle.com/javase/tutorial/essential/io/fileOps.html


java.nio.Path
• Mejora la clase File (cualquier fich./carpeta)
– Construcción
• Path p1=Paths.get("/tmp/foo"); // utilidad Paths
• No tiene constructor público
– Consulta
• getFileName() - nombre de fichero/carpeta
• getName(i), getNameCount() - subcarpetas
• getParent(), getRoot(), subpath(i,j)
– Modificación
• normalize() - elimina redundancias
• toAbsolutePath() - convierte a path absoluto
• toUri() - convierte a URI

Programación III http://docs.oracle.com/javase/tutorial/essential/io/fileio.html


Gestionando datos en disco
• ¿Cómo hacer persistentes los datos de una aplicación
en Java?
– Lógica de datos desde un proyecto
– Distintas maneras de que los datos perduren

Programación III
Lógica de datos
• En cada proyecto nos tenemos que plantear
– ¿Qué datos son fijos y cuáles variables?
– ¿Qué datos deben perdurar entre ejecuciones?
– ¿Podemos cargar todos los datos en memoria?
• ¿Nos caben? ¿Es eficiente?
• Para cada tipo de datos necesitaremos definir una
estrategia de acceso a esos datos
– Veamos algunas

Programación III
Datos fijos en memoria
• Si los datos que necesitamos no cambian y son pocos,
podemos definirlos en el mismo programa
– Como un array u otra estructura (mapa,lista)
– Ejemplos:
String[] diasSem = {"lunes", "martes", ... "domingo"};
Usuarios administradores = {
new Usuario( "andoni", "miclave" ), ... };

– Cualquier cambio obligaría a cambiar el código de


nuestra aplicación (nada recomendable)
• Hay dos problemas en ese código, ¿podéis identificarlos?

Programación III
Datos variables y heterogéneos
• Si los datos cambian y son pocos, se pueden usar
ficheros de texto (.ini, .cfg, .prop, .xml...)
– Fichero de "configuración" de aplicación
– Método de carga inicial de fichero a memoria
– Método de cambio (de algún dato)
• Guardando de nuevo el fichero
– Ejemplos: carpeta en curso, último usuario con login,
fecha último acceso...
carpeta=c:\users\all\datos
usuario=maria
ventana=640,400

Programación III
Cómo guardar datos variables?
• A mano
– Con ficheros de texto
• Con la API de Java
– En fichero de texto - Properties
• setProperty( clave, valor )
• getProperty( clave )
• loadFromXML( fic ) / storeToXML( fic, título )
• (ver EjemploProperties.java)
– En registro de sistema - Preferences
• (ver ejemplo en cap. 1)

Programación III
Datos variables homogéneos
• Habitualmente nos encontraremos:
– Tenemos "n" objetos con los que trabajar
– Hay que guardarlos entre ejecuciones de la
aplicación para poder acceder a ellos
• Aspectos a considerar:
– ¿Caben todos en memoria?
• ¿Cuándo los guardamos?
– ¿Puede cambiar su estructura con el tiempo?
(nuevos atributos)

Programación III
Enfoque 2: Ficheros binarios
• Java permite serializar objetos
– Cargar al principio, guardar al final
– Un fichero por cada tipo de objeto (clase)
– writeObject(o), readObject()
• ¿Cómo funciona?
– Java escribe todos los atributos de cada objeto
– Se guarda en formato binario consecutivamente en
el fichero
– Cualquier cambio en la estructura del objeto hará
que no se puedan leer ficheros anteriores
• Se leen Object - hay que hacer un cast

Programación III
Ficheros binarios: Serializable
– Toda clase que queramos guardar debe implementar
el interfaz java.io.Serializable
• Sin métodos
• Debe asociar un número de versión único
static final long serialVersionUID = 1234567890L;
• Cada writeObject() guarda ese número y todos los datos
• Cada readObject() lee ese número y lo compara al
interpretar el objeto que se ha leído
(InvalidClassException)
– Todos los atributos y las superclases deben ser a su
vez serializables
• Deben tener constructor vacío - lo usa el readObject()
Programación III
Ejemplo de serialización
private void escribeAFichero() {
try {
FileOutputStream fout = new FileOutputStream(“a.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject( miDato );
oos.close();
} catch (IOException e) { ... }
}
private void leeDeFichero() {
try {
FileInputStream fin = new FileInputStream(“a.dat");
ObjectInputStream ois = new ObjectInputStream(fin);
miDato = (MiClase) ois.readObject();
ois.close();
} catch (Exception e) { ... }
} (ver EjemploFicheros.java)

Programación III
Enfoque 1: Ficheros de texto
– Un fichero por tipo de objeto (clase)
– Cada clase debe tener al menos:
• Un lector del fichero (cargaDeFic( ... ))
• Un escritor del fichero (guardaEnFic( ... ))
– El formato del fichero puede ser libre o estándar
(XML, el más utilizado)
– Es recomendable utilizar etiquetas
• Permiten que cambios de atributos en la clase sean
soportables, identificando qué dato se lee (versiones
acumulativas de los métodos lectores)

Programación III
Ficheros de texto (2)
• Por ejemplo un fichero de texto de usuarios podría
tener esta pinta si separamos sus atributos con comas:
Andoni,Eguíluz Morán,miPass,636124523
Luis,Gómez Ruiz,xxyyww84,666000111
...

Programación III
Ficheros de texto (3)
• Podríamos también separar por líneas sus atributos, o
incluso poner tags para evitar posibles errores:
[USUARIO]
[Nombre]Andoni
[Apellidos]Eguíluz Morán
[Contraseña]Aquí la voy a poner!
[FINUSUARIO]
[USUARIO]
[Nombre]Luis
[Apellidos]Gómez Ruiz
[Contraseña]xxyyww84
[FINUSUARIO]

Programación III
Ficheros de texto (4)
• O mejor usar un formato estándar XML:
<root>
<USUARIOS>
<USUARIO>
<nombre valor="Andoni"/>
<apellidos valor="Eguíluz Morán/>
<contraseña valor="Aquí la voy a poner!"/>
</USUARIO>
<USUARIO>
<nombre valor="Luis"/>
<apellidos valor="Gómez Ruiz/>
<contraseña valor="xxyyww84"/>
</USUARIO>
</USUARIOS>
</root>

Programación III
Programando la lectura
• Por ejemplo: (ver EjemploFicheros.java)
try {
BufferedReader brFich = new BufferedReader( new
InputStreamReader( new FileInputStream(nomFic) ) );
String linea = brFich.readLine();
while (linea != null) {
// Proceso de línea
// (depende de cómo esté implementado)
...
linea = brFich.readLine();
}
brFich.close();
} catch (Exception e) { // FileNotFound, IO
e.printStackTrace();
}

Programación III
Escritura de ficheros de texto
• Por ejemplo:
try {
BufferedWriter brFich = new BufferedWriter( new
OutputStreamWriter(new FileOutputStream(nomFic)) );
for (DatoAEscribir d : miEstructuraDeDatos) {
// Proceso de dato a línea
// Depende del modo de escritura
...
}
brFich.close();
} catch (Exception e) {
e.printStackTrace();
}

Programación III
Enfoque 3: Base de datos
– Si los datos no caben en memoria, o si queremos
guardar cada cambio y no toda la estructura, bases
de datos en lugar de ficheros
• Acceso a un solo dato sin leer todo el fichero
• Acceso a datos buscando por criterios configurables
– Estructura optimizada para la búsqueda
• Relaciones entre datos (tablas)

Programación III
Base de Datos
• Java no incluye ningún SGBD
– Pero sí una API para enlazar con cualquier BD: JDBC
– Por ejemplo, SQLite
• Driver JDBC-SQLite: https://bitbucket.org/xerial/sqlite-jdbc
(Hay que enlazar el .jar en el classpath)
• (Opcional) Sistema visual de administración de la BD:
http://sourceforge.net/projects/sqliteman/
(Otra opción, válida para Mac: http://sqlitebrowser.org/)
• Web general: http://www.sqlite.org/
• SQLite no tiene un SGBD adicional, ni necesita servidor, es
un programa (que va incluido en el .jar)

Programación III
ResulSet ResulSet ResulSet

• Estructura Statement
Prepared Callable
Statement Statement
JDBC
Connection

Application

DriverManager

JDBC-ODBC
Oracle Driver Sybase Driver
Bridge

ODBC Driver

Oracle Sybase
Database Database

ODBC
Database

Programación III
Driver JDBC
– Todas la configuraciones necesitan de un driver JDBC
específico para la base de datos que se vaya a usar.
– Para ejemplos usaremos el driver JDBC-SQLite
• Integra con un .jar que incluye el motor SQLite.
• Otras opciones: JDBC - ODBC
• Lo normal es una pasarela que conecta con la BD instalada
en el SO (Oracle p ej.)

Programación III
Inicio de código BD
• Importar clases de JDBC:
import java.sql.*;
• Cargar driver (class loader)
Class.forName("org.sqlite.JDBC");
• Establecer conexión / lanzar sents. SQL:
Connection conn = null;
try {
conn = DriverManager.getConnection(
“jdbc:sqlite:n.db“ );

– Tb usuario, password en la conexión

Programación III
Sentencia JDBC
• Crear un objeto JDBC Statement
– Los objetos Statement son necesarios para ejecutar
sentencias SQL sobre la base de datos.
– Los objetos Statement se crean a través del objeto
Connection.
Statement stmt = conn.createStatement();
– Dos tipos de sentencias SQL:
• Consultas SQL ➔ Método executeQuery()
• Sentencias que modifican la BD ➔ Método
executeUpdate()

Programación III
executeUpdate()
– Para sentencias de tipo INSERT, DELETE, UPDATE, CREATE,
DROP, ALTER,...
– Ejemplos:
• Inserción de una nueva fila en la tabla alumnos
String sentencia = "INSERT INTO ALUMNOS
VALUES('666','JORGE RUIZ',26)";
stmt.executeUpdate(sentencia);
• Borrado de una fila de la tabla alumnos
String sentencia = "DELETE FROM ALUMNOS WHERE
EDAD = 20";
stmt.executeUpdate(sentencia);
• Modificación del contenido de una fila de la tabla alumnos
String sentencia = "UPDATE ALUMNOS SET EDAD=19
WHERE DNI = '666'";
stmt.executeUpdate(sentencia);

Programación III
executeQuery()
• Método EXECUTEQUERY
– Para sentencias SQL de tipo “SELECT” (consultas)
– Ejemplos:
• Obtener todos los alumnos de la tabla alumnos
stmt.executeQuery(“SELECT * FROM ALUMNOS”);
• Obtener el dni y el nombre de los de 22 años
String query = “select dni, nombre from
Alumnos where edad = 22”;
stmt.executeQuery(query);
– Estas consultas SQL devuelven como resultado un conjunto
de filas ➔ ¿Cómo podemos recoger estos resultados?

Programación III
ResultSet
• Manipulación de los resultados generados
– El interfaz ResultSet nos permite recoger los
resultados (filas) generados por una consulta SQL.
Objeto “tabla” con filas y columnas.
– Posee una serie de métodos para “navegar” entre las
filas y columnas de dicha tabla resultado: next( ) y
getXXX( )
– Método getXXX( nombreCampo / posCampo )
• Recupera valor de una columna de la fila en curso.
• getInt( ) -> INTEGER / getFloat( ) -> REAL
• getDouble( ) -> FLOAT, DOUBLE
• getString( ) ->CHAR, VARCHAR, LONGVARCHAR
• getBoolean( ) -> BIT

Programación III
ResultSet (2)
– Ejemplo:
• Consulta a realizar: “SELECT NOMBRE, EDAD FROM ALUMNOS”
• Tabla resultado que se obtiene:

NOMBRE EDAD
Jane Markham 23
Louis Smith 21
Woodrow Lang 32
John Smith 19

Programa que realiza la consulta y visualiza los resultados:

Programación III
Ejemplo ResultSet
Statement stmt = con.createStatement();
String query = “SELECT NOMBRE, EDAD FROM ALUMNOS”;
ResultSet rs = stmt.executeQuery(query);
while(rs.next())
{
System.out.print(“Nombre: ” + rs.getString(1));
System.out.print(“, ”);
System.out.println(“Edad: ” + rs.getInt(“EDAD”));
}
rs.close();

Programación III
Acabando...
• Cerrar los recursos abiertos
• Las Connection
• Los Statement
• Los Resultset
– ... mediante el método close( )
rs.close();
stmt.close();
con.close();

Programación III
Excepciones JDBC
• La mayoría de las operaciones del API JDBC pueden lanzar la
excepción SQLException.
• Esta excepción se produce cuando se da algún error en el
acceso a la base de datos (error de conexión, sentencias
SQL incorrectas,...)
• Por tanto, será necesario capturarla:
try{
...
}
catch(SQLException se){
System.out.println(“SQL Exception: “ +
se.getMessage());
se.printStackTrace(System.out);
}

Programación III
¿Y el SQL?
• La sintaxis la procesa el SGBD, Java sólo pasa el string
con la sentencia completa
– Sintaxis SQL
• INSERT INTO tabla (campo1, campo2) VALUES
(valor1, valor2)
• UPDATE tabla SET campo1 = valor1, campo2 =
valor2 [WHERE campo1 = valor1]
• DELETE FROM tabla WHERE campo = valor
– Comillas simples para Strings / doble ' para '
– Evitar caracteres especiales
– Y mucho cuidado al construir sentencias largas...

Programación III
Minipráctica
• Clase con main():
– 1. Crear tabla Usuario con campos nick, pass
– 2. Añadir una fila 'admin' - 'admin' [insert]
– 3. Comprobar creación/datos con SQLiteMan
– 3. Probar a ejecutar otra vez ¿cómo arreglarlo?
– 4. ¿Cómo hacer que solo se inserte 'admin' si no
existe ya antes? [select]
– 5. Hacer una pequeña ventana que permita insertar
usuarios nuevos de forma interactiva
– 6. Añadir a la ventana botón de borrado
– 7. ¿Puedes hacer que esto casque? ¿Cómo?

Programación III
¿Es esta la mejor manera?
• Crear strings con sentencias SQL es fácil pero...
– Errores de lógica (concatenaciones)
– Peligros de datos (SQL injections):
https://www.hacksplaining.com/exercises/sql-
injection
• Los strings deben ser "saneados" antes de ser introducidos
en las sentencias
– No es la forma más eficiente
• Está bien usarlo para empezar, pero no es la mejor
manera de programar el día de mañana:
– Sentencias preparadas (Java)
– Procedimientos almacenados (SGBD)
Programación III
PreparedStatement
• Ayudan a crear sentencias rellenando valores

PreparedStatement pstmt = null;


con = DriverManager.getConnection(
"jdbc:default:connection");
pstmt = con.prepareStatement(
"UPDATE EMPLOYEES SET CAR_NUMBER = ? " +
"WHERE EMPLOYEE_NUMBER = ?");
pstmt.setInt(1, numCoche);
pstmt.setInt(2, numEmpleado);
pstmt.executeUpdate();
• Y evitan problemas de caracteres!!!
• También pueden repetirse cambiando valores

Programación III
Transacciones
• En programación de BD sencilla no hacen falta
– Cada execute hace y confirma la sentencia
• Pero si queremos permitir recuperación de un proceso
complejo que funciona en bloque...
try {
con.setAutoCommit(false);
... varias actualizaciones de BD ...
con.commit();
} catch (SQLException e ) {
try {
con.rollback();
} catch(SQLException excep) {}
} finally {
con.setAutoCommit(true);
}

Programación III
Cómo gestiono los datos
• Si son pocos:
– 1. Cargar de fichero (BD) a memoria
– 2. Manejar en memoria
– 3. Reescribir en fichero (BD)
• Si son muchos o en cualquier caso en BD:
– 1. Abrir BD
– 2. Buscar-modificar en BD
– 3. Cerrar BD

Programación III
Particularidades
• boolean es un tipo que varios SGBD no soportan
• bigint (el long de Java) también depende
• date – revisar formato en cada SGBD (usualmente
AAAA/MM/DD)
• binarios – permitido pero distinto en cada SGBD.
Cuando queremos guardar un recurso multimedia, es
muy habitual guardar el path y gestionar aparte el
fichero (fuera de la BD)

Programación III
Razonamiento sobre BD/Clases
• Ejemplos de datos de vuestros proyectos
– ¿Qué tablas?
– ¿Qué clases/objetos?
• Relaciones
– Tabla simple (1 a 1)
– 1an
– nan
– Herencia

Programación III
Clase a tabla (1 a 1)
Carta

int numero
Palo palo
int valor

Clase
Tabla Carta

id: integer
numero: integer
palo: char(10)/integer
valor: integer

Tabla
Programación III
Clase a tabla (1 a n)
Tabla Pista
Pista
idPista: integer
String nombre nombre: varchar(100)
Deporte codDeporte codDeporte: char(15)
String localización loc: varchar(100)
ArrayList<Reserva>
reservas
Tabla Reserva
idReserva: integer
Reserva codUsuario: char(10)
horaInicio: integer
String codUsuario horaFin: integer
int horaInicio numDeportistas: int
int horaFin conLuz: bit
int numDeportistas
boolean conLuz numSec: integer
idPista: integer

Clases Tablas
Programación III
1 a n – también con repets
Pedido

String cliente
Date fecha
double importe Tabla Pedido
ArrayList<String> idPedido: integer
lineas cliente: varchar(100)
fecha: date
importe: float

Tabla LineaPedido
linea: varchar(1000)
numSec: integer
idPedido: integer

Clases Tablas
Programación III
Clase a tabla (m a n)
MapaNivel Tabla MapaNivel

String nombre idMapaNivel: integer


String descripcion nombre: varchar(100)
int secNivel descripcion:varchar(1000)
ArrayList<Tile> tiles secNivel: integer

Tabla Tile
Tile
posX: integer
TileModel tileModel posY: integer
int posX idMapaNivel: integer
int posY idTileModel: integer

TileModel Tabla TileModel

String nombre idTileModel: integer


String ficGrafico nombre: varchar(30)
ficGrafico: varchar(100)

Programación III Clases Tablas


Clase a tabla (herencia)
Tabla Usuario
Usuario
idUsuario: integer
String nick nick: varchar(20)
String password password: varchar(20)
String nombre nombre: varchar(50)

UsuarioDePago Tabla UsuarioDePago

int visaNum idUsuario: integer


int visaExpDate visaNum: integer
long fechaRegistro visaExpDate: integer
fechaReg: date
Clases
Tablas
Programación III
¿Local o en la nube?

driver (jar)

Programación III
¿Cómo ir a la nube?
– Servidor propio o servicio contratado/gratuito
• Por ejemplo www.heroku.com
– Instalar un servidor de base de datos
• Por ejemplo postgres (www.postgresql.org/)
– Acceder con SQL y el driver que corresponda
https://jdbc.postgresql.org/download.html
Class.forName("org.postgresql.Driver");
– Cadena de conexión que corresponda
"jdbc:postgresql://urlbd?sslmode=require"
urlbd = nombreservidor:5432/nombrebd
– Administración adicional si se requiere
• Por ejemplo EMS SQL Manager for PostgreSQL

Programación III
¿Seguridad en la nube?
– Arquitectura más fácil: BD pública (usu/pass)

driver

• ¿Recomendable? No! Muy insegura


– Mejor pero más complejo: Arquitectura C/S

driver

• Comunicación supervisada, acceso BD centralizado
Programación III
Ejemplo de arquitectura C/S
• Ver paquete es.deusto.prog3.cap03.cs
• Programa Servidor (ejecutar 1)
• Programa Cliente (ejecutar n)
• Solo el servidor accede a la BD

Programación III
Ejercicios
• Toma cualquier clase sencilla que tengas definida y
realiza métodos para guardar y cargar los objetos de
esta clase a ficheros de texto, binarios, y bases de
datos.
• Prueba a visualizar y modificar la estructura de la BD
con sqliteman.
• Crea una base de datos remota en heroku y prueba a
acceder a ella con postgresql.

Programación III
Ejercicios 2
• En el paquete ejemploPartidas…
– Falta algo importante. Busca errores probando a hackear
la BD con testcase nuevo que meta algún apellido
irlandés (¿O’Reilly?). Solucionar BD.java
– Añadir el update de tabla de puntuación y añadir test de
ese update (¿qué hay que añadir?)
– Modificar alguno de los métodos con
preparedStatements en lugar de statements normales
– Programa un ejemplo que meta varios usuarios /
puntuaciones en la BD y observa esas tablas con el
administrador de sqlite
– Si te va bien para el proyecto… programa una edición de
ventana interactiva de usuario/partidas con este modelo
de BD o algún cambio

Programación III
Anexo: resumen SQL
• Operativa datos (CRUD):
– SELECT col1, col2,... colN FROM tabla
[WHERE condición]
[ORDER BY col {ASC|DESC}]
– SELECT * FROM tabla ...
– INSERT INTO tabla (col1, col2,... colN)
VALUES (val1, val2... valN)
– UPDATE tabla SET col1 = val1, col2 = val2...
[WHERE condición]
– DELETE FROM tabla WHERE condición
Programación III
Resumen SQL (2)
• Modificación estructura de BD:
– CREATE TABLE table_name(
col1 datatype,
col2 datatype, ...
PRIMARY KEY(col1, col2,...)
)
– DROP TABLE tabla;
– ALTER TABLE tabla {ADD|DROP|MODIFY} col
{datatype}
– CREATE DATABASE basedatos;
https://www.tutorialspoint.com/sql/sql-syntax.htm

Programación III
Anexo 2: Proceso XML
• Como es tan habitual trabajar con ficheros XML, Java
incorpora varias maneras de trabajar con ellos en su
API
– Preferences genera y lee XML
– Logger genera XML
– ...
• Si queremos procesarlo (p.ej. para los logs) hay una
minilibrería llamada SAX que lo permite muy fácilmente
– Ver EjemploProcesoLog.java

Programación III

También podría gustarte