0% encontró este documento útil (0 votos)
6 vistas98 páginas

Ud 07

Este documento describe los fundamentos del lenguaje SQL y cómo se puede acceder a datos en bases de datos relacionales desde Java utilizando la tecnología JDBC. Explica conceptos básicos de SQL como tablas, columnas, filas y sentencias para crear, modificar y eliminar datos. También describe los pasos para establecer una conexión JDBC y ejecutar sentencias SQL.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
6 vistas98 páginas

Ud 07

Este documento describe los fundamentos del lenguaje SQL y cómo se puede acceder a datos en bases de datos relacionales desde Java utilizando la tecnología JDBC. Explica conceptos básicos de SQL como tablas, columnas, filas y sentencias para crear, modificar y eliminar datos. También describe los pasos para establecer una conexión JDBC y ejecutar sentencias SQL.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 98

7

ANÁLISIS Y PROGRAMACIÓN EN JAVA

Acceso a datos en Java


ÍNDICE
7 7.1 7.2 7.3 7.4 7.5 7.6

Fundamentos La tecnología Ejecución de Manipulación Bases de datos XML como


del lenguaje JDBC sentencias de de resultados en Java almacenamiento
SQL acción de datos
7.7 7.8

Acceso a Serialización
ficheros de ficheros
7.1 Fundamentos del
lenguaje SQL

C O M E N Z A R
Fundamentos del lenguaje SQL

SQL es el lenguaje estándar para


interactuar con las bases de datos
relacionales
y prácticamente todos los sistemas
administradores de bases de datos actuales lo
soportan.
Fundamentos del lenguaje SQL

Las unidades básicas del SQL son


tablas, columnas y filas.

Tablas: proporcionan una forma simple de


relacionar los datos que las componen.

Columnas: representan un dato presente


en la tabla.

Filas: representan un registro o entrada de


las tablas.
Fundamentos del lenguaje SQL

Para crear una base de datos SQL proporciona la sentencia:

CREATE DATABASE <base de datos>

Si queremos eliminar una base de datos, la sentencia será:

DROP DATABASE <base de datos>

Para crear una tabla SQL proporciona la sentencia:

CREATE TABLE <tabla>(<columna 1> ,<columna 2>…)

Donde columna n se formula según la sintaxis siguiente:


<columna n> <tipo de dato> DEFAULT <expresión>
<constante 1> <constante 2>…
Fundamentos del lenguaje SQL

DEFAULT permite especificar un valor por omisión para la columna. Si queremos indicar la
forma o característica de cada columna, se pueden utilizar las constantes:

NOT NULL (No se permiten valores nulos: NULL)

PRIMARY KEY. Se utiliza para definir la columna como clave principal de la


tabla. La columna no puede contener valores nulos ni duplicados, por lo que
dos filas no pueden tener el mismo valor en esa columna. Una tabla solo puede
contener una restricción PRIMARY KEY.

UNIQUE. Indica que la columna no permite valores duplicados, por lo que dos filas no
pueden tener el mismo valor en esa columna. Una tabla puede contener varias
restricciones UNIQUE. Normalmente se utiliza para que el sistema compruebe que no
se añaden valores que ya existen.
Fundamentos del lenguaje SQL

Ejemplo

Vamos a ver un ejemplo donde se crea la tabla teléfonos.

CREATE TABLE teléfonos (

nombre CHAR(30) NOT NULL.

dirección CHAR(30) NOT NULL.

teléfono CHAR(12) PRIMARY KEY NOT NULL.

Observaciones CHAR(240)

)
Fundamentos del lenguaje SQL

Pa r a e s c r i b i r d a t o s e n u n a t a b l a , S Q L p r o p o r c i o n a l a s e n t e n c i a :

INSERT INTO <tabla> (<columna 1>,(<columna 2>…)

VALUES (<expresión 1>,<expresión 2>…),…

A continuación vamos a añadir a nuestro ejemplo de la tabla teléfonos


una nueva fila con los valores de las columnas especificados:

INSERT INTO teléfonos


VALUE (´Emilio Lopez Aguirre´, ´Madrid´,
´911234567, ´Ninguna´)
Fundamentos del lenguaje SQL

Si queremos modificar datos en una tabla la sentencia que nos


proporciona SQL será:

UPDATE <tabla>
SET <columna 1 = (<expresión 1> | NULL)
, <columna 2 = (<expresión 2> |
NULL)…
WHERE <condición de búsqueda>

Va m o s a m o d i f i c a r e n n u e s t ro e j e m p l o d e t a b l a t e l é f o n o s l a
dirección de la persona que se mostraba:

UPDATE teléfonos
SET dirección= ´Parla, Madrid´
WHERE telefono=´917654321´
Fundamentos del lenguaje SQL

Si queremos borrar registros en una tabla, la sentencia que nos


proporciona SQL es:

DELETE FROM <tabla> WHERE <condición de búsqueda>

Po d e m o s q u i t a r d e l a t a b l a t e l é f o n o s e l r e g i s t r o q u e t i e n e l a c l a v e
especificada:

DELETE FROM teléfonos WHERE telefono=´986334577´

Cualquier tabla de la se hayan quitado todas las filas siguen


permaneciendo en la base de datos. Si queremos quitarla de la
base de datos utilizaremos:

DROP TABLE <tabla>


Fundamentos del lenguaje SQL

Si queremos seleccionar datos de una tabla, utilizaremos la


siguiente sentencia de SQL:

SELECT ALL |DISTINCT <lista de selección>


FROM <tablas>
WHERE <condiciones de selección>
ORDER BY <columna 1> ASC|DESC , <columna 2> ASC|DESC…

Pa r a l i s t a r t o d a s l a s f i l a s d e l a t a b l a t e l é f o n o s u t i l i z a r e m o s :

SELECT * FROM teléfonos

Si queremos listar todas las filas de la tabla teléfonos por orden


ascendente utilizaremos:

SELECT * FROM teléfonos ORDER BY nombre


7.2 La tecnología
JDBC

C O M E N Z A R
La tecnología JDBC

JDBC
(Java DataBase Connectivity)

JDBC (Java DataBase Connectivity) es una API de Java proporcionada por un conjunto de
clases que permite ejecutar instrucciones SQL para manipular y gestionar bases de datos
relacionales.

Para que una aplicación Java pueda hacer operaciones sobre una base de datos, antes tiene
que establecer una conexión con ella que se realiza a través de un controlador (driver).

La función de este driver será traducir los mensajes de bajo nivel del sistema base de daos a
mensajes de bajo nivel de la API JDBC y viceversa.
La tecnología JDBC

La API JDBC se proporciona en dos paquetes:

1 2
Paquete javax.sql. Paquete java.sql. Este paquete forma parte de J2SE y contiene las interfaces y
clases Java fundamentales de JDBC, de las cuales cualquier aplicación JAVA utiliza
casi siempre 4:
o DriverManager. Se utiliza para realizar la conexión con la base de datos.
Para esto utilizamos el método getConnection que devuelve el objeto
Connection con la conexión solicitada.
o Connection. Es el objeto que se utiliza para construir el objeto Statement
que usamos para enviar sentencias SQL a la base de datos. Para esto
debemos invocar al método createStatement que devuelve un objeto
Statement.
o Statement. Este objeto permite, a través de su método executeQuery,
ejecutar una sentencia SQL sobre la base de y devuelve el objeto
ResultSet.
o ResultSet. Es una tabla de datos que representa al conjunto de resultados
generado al ejecutar la sentencia SQL sobre la base de datos. Los métodos
de esta clase nos permiten acceder a los registros del conjunto de
resultados obtenido.
7.3 Ejecución de
sentencias de
acción
C O M E N Z A R
Ejecución de sentencias de acción

Ejecución de consultas de selección


Antes de poder ejecutar una sentencia SQL,
es necesario obtener un objeto de tipo Statement. Una vez creado dicho
objeto, podrá ser utilizado para ejecutar cualquier operación contra la base
de datos.
La finalidad de un objeto Statement es ejecutar una instrucción SQL que
puede o no devolver resultados. Para ello, la interfaz Statement dispone de
los siguientes métodos:

• executeQuery(), para sentencias SQL que recuperen datos en un único


objeto ResultSet.

• executeUpdate(), para realizar actualizaciones que no devuelvan un


ResultSet. Por ejemplo, sentencias DML SQL (Data Manipulation Language)
como INSERT, UPDATE y DELETE, o sentencias DDL SQL (Data Definition
Language) como CREATE TABLE, DROP TABLE y ALTER TABLE. El valor que
devuelve executeUpdate() es un entero que indica el número de filas que
se vieron afectadas. Las sentencias que no operan en filas, como CREATE
TABLE o DROP TABLE, devuelven el valor cero.
Ejecución de sentencias de acción

Connection
Connection también tiene unos métodos que devuelven un objeto de tipo

PreparedStatement para la ejecución de sentencias. Se precompilan (son más rápidas)

y aceptan parámetros de entrada en tiempo de ejecución.

Por ejemplo, en el siguiente código se ha creado una sentencia para borrar una fila de

la tabla “Customer” pero se ha añadido un parámetro contra la propiedad “customerid”,

posteriormente, al ejecutar la sentencia, será establecido con el valor adecuado .


Ejecución de sentencias de acción

Manejo de conjuntos de registros


Como hemos visto anteriormente, utilizaremos executeQuery(), para recuperar registros
(datos) desde base de datos.

Este método nos devuelve un objeto de tipo


ResultSet, cuyas características son:

• Encapsula el conjunto de resultados.


• Para obtener el valor de cada campo hay que usar el
método getX("campo") correspondiente al tipo del valor
SQL: (getString(), getInt(), getDate(), etc).
• Para pasar al siguiente registro se usa el método next().
Devuelve false cuando no hay más registros.
• Por defecto solo se puede recorrer hacia delante
• Parar recuperar la fila actual se utiliza getRow().
Ejecución de sentencias de acción

Ejecución de consultas
de manipulación de datos

Sentencias DML SQL (Data Manipulation 1 CREATE, se usa para crear una base de datos,

Language) nos permiten definir estructuras tabla, vistas, etc.

que almacenarán los datos, así como los


2 ALTER, se utiliza para modificar la estructura,
procedimientos o funciones que permiten
por ejemplo, añadir o borrar columnas de una
consultarlas.
tabla.

Para definir las estructuras, 3 DROP, con esta sentencia se puede eliminar los
objetos de la estructura como tablas, índices,
disponemos de tres sentencias:
etc.
Ejecución de sentencias de acción

Ejecución de consultas
de definición de datos

1 SELECT, esta sentencia se utiliza para


Sentencias DML SQL (Data Manipulation Language)
realizar consultas sobre los datos.

nos permite introducir datos para posteriormente INSERT, con esta instrucción podemos
2
insertar los valores en una base de
realizar tareas de consultas o modificaciones de los
datos.
datos que contiente la base de datos.
UPDATE, sirve para modificar los
Las sentencias que se utilizan para manipular 3 valores de uno o varios registros.
datos son:
DELETE, se utiliza para eliminar las finas de
4
una tabla.
Ejecución de sentencias de acción

El siguiente código muestra un ejemplo completo con diferentes sentencias


vistas en los puntos anteriores.

String createTableBank = "CREATE TABLE BANCO (cliente VARCHAR(100) NOT NULL, password VARCHAR(20) NOT
NULL, balance Integer NOT NULL, PRIMARY KEY(cliente))";
statement.executeUpdate(createTableBank);

String insert = "INSERT INTO BANCO VALUES('cliente1','1234',2)";


statement.executeUpdate(insert);

String select = "SELECT * FROM BANCO";


ResultSet rs = statement.executeQuery(select);

while (rs.next()) {
System.out.println(rs.getString("cliente") + " - " + rs.getInt("balance"));
}
https://player.vimeo.com/video/728033415?h=3f6e90c9
72

https://player.vimeo.com/video/728033415?h=3f6e90c972
https://player.vimeo.com/video/728033435?h=c62d5980
5e

https://player.vimeo.com/video/728033435?h=c62d59805e
7.4 Manipulación de
resultados
C O M E N Z A R
Manipulación de resultados

La interfaz Java ResultSet es parte del paquete java.sql.

El objeto ResultSet se utiliza para acceder a los resultados de la consulta recuperados


de las bases de datos relacionales.

Se pueden utilizar los métodos de navegación y obtención que proporciona ResultSet


para acceder a los registros de la base de datos uno por uno y para actualizar datos.

ResultSet es esencialmente una tabla que contiene toda la información que debe
devolverse de una consulta específica, así como algunos metadatos esenciales.

Un ResultSet es una tabla de datos que representa un conjunto de resultados de una


base de datos, que generalmente se genera al ejecutar una declaración que consulta la
base de datos.

Se obtiene un ResultSet después de ejecutar una consulta. La conexión y la declaración


deberán crearse antes de la ejecución.
Manipulación de resultados

ResultSet tiene métodos que se pueden clasificar en 3 categorías:

Métodos de navegación: para navegar por el conjunto de resultados


beforeFirst(), afterLast(), first(), last(), next(), previous().

Obtener métodos: contiene métodos para consultar la posición actual


del conjunto de resultados como getRow(), isAfterLast(),
isBeforeFirst(), isFirst(), isLast().

Métodos de actualización: contiene un método refreshRow() para


actualizar el valor con los valores más recientes.
7.5 Bases de datos
en Java
C O M E N Z A R
Bases de datos en Java

Una vez obtenida la conexión a la


BD, podemos utilizarla para realizar
consultas, inserción y/o borrado de
datos de dicha BD.

Todas estas operaciones se realizarán


mediante lenguaje SQL.
Bases de datos en Java

Gestión de transacciones
Iniciar una transacción

En entornos multiusuario (por ejemplo, para aplicaciones web) hay que controlar el
acceso concurrente a la BD para evitar inconsistencias.

La transacción es una unidad de trabajo lógica. Engloba un conjunto de instrucciones


sobre la base de datos, si algo va mal, hace una marcha atrás para dejar todo en el
estado anterior, si finalmente todo ha funcionado bien realiza los cambios en la base de
datos.
Bases de datos en Java

Iniciar una transacción


Por defecto se funciona en modo autocommit. Es
decir, cada instrucción sobre la BD va en su propia
transacción. Esto es seguro, pero ineficiente.
Se desactiva con la siguiente instrucción:
https://player.vimeo.com/video/728033451?h=0af32c10
0b

https://player.vimeo.com/video/728033451?h=0af32c100b
Bases de datos en Java

Detener una transacción


Para finalizar un transacción y realizar definitivamente los
cambios en base de datos utilizaremos el método commit() que
hace efectivos todos los cambios desde el último commit/rollback y
libera los bloqueos de la BD que tuviera el objeto Connection.
Bases de datos en Java

Respuesta
tras error
Si obtenemos una excepción
(SQLException) al ejecutar nuestras
sentencias, podemos deshacer todos
los cambios realizados en la transacción
y liberar los bloqueos de la base de
datos con el método rollback().
Bases de datos en Java

Excepciones del API JDBC


Cuando algo va mal al ejecutar las sentencias, JAVA nos lanza excepciones del tipo SQLException.
Es obligatorio capturar y tratar estas excepciones. Se puede obtener información adicional sobre el
error con los métodos:

getMessage() getSQLState() getErrorCode()

Nos da el mensaje de Texto de SQLState Código de error (un


error de la excepción. según la convención número entero)
X/Open o SQL:2003. específico del
vendedor.

Existen otros tipos de excepciones SQLWarning, que no son obligatorio capturar y que representan errores
leves de objectos como Connection, Statement o ResultSet.
7.6 XML como
almacenamiento
de datos
C O M E N Z A R
XML como almacenamiento de datos

Introducción a
las bases de
datos XML
Una base de datos XML constituye un sistema software que

da persistencia a datos almacenados en formato XML.

Estos datos pueden ser interrogados, exportados y

serializados. Las bases de datos XML están generalmente

asociadas con las bases de datos documentales.

Existen dos grandes clases de bases de datos XML:


XML habilitado
Éstas bien pueden mapear XML en estructuras
tradicionales de bases de datos (como las relacionales),
aceptando XML como entrada y formateando en XML la
salida, o más recientemente soportando tipos XML
nativos en la propia base de datos. Esto implica que la
base de datos procesa el XML internamente (lo opuesto
a soportarlo mediante middleware).

XML nativo (NXD)


El modelo interno de estas bases de datos usa
documentos XML como la unidad elemental de
almacenamiento, los cuales no han de almacenarse
necesariamente en formato de texto.
XML como almacenamiento de datos

Bases de datos documentales


Las bases de datos orientadas a documentos son una de las principales categorías de las bases de datos NoSQl, y
la popularidad del término ha crecido en los últimos tiempos. Las bases de datos XML son una subclase de base de
datos orientadas a documentos que están optimizadas para trabajar con documentos XML. Las bases de datos de
gráficos son similares, pero añaden otra capa de relaciones que permiten un acceso más rápido.

Las bases de datos de documentos contrastan fuertemente con la base de datos relacional
tradicional (RDB). Las bases de datos relacionales generalmente almacenan datos en tablas
separadas definidas por el programador, y un solo objeto puede extenderse a varias tablas. Las
bases de datos de documentos almacenan toda la información para un objeto dado en una sola
instancia en la base de datos, y cada objeto almacenado puede ser diferente de los demás. Esto
elimina la necesidad de mapeo relacional de objetos al cargar datos en la base de datos.
XML como almacenamiento de datos

Tratamiento de bases de datos XML


Establecimiento y cierre de conexiones
En este capítulo crearemos un ejemplo completo;
una aplicación que lea un fichero XML y realice
diferentes consultas a ese fichero.
Para comenzar, es necesario crear un objecto de
tipo org.w3c.dom.Document, para ello podemos
utilizar el siguiente método:

Si realizamos instrucciones de modificación del fichero XML


y queremos guardar los cambios en el fichero deberemos
hacer algo como:
XML como almacenamiento de datos

T R ATA M I E N TO D E B A S E S D E DATO S X M L

Lenguaje de consulta
para XML; Xquery
XPath es una sintaxis utilizada para describir partes de un documento XML.
Con XPath, se puede hacer referencia al primer elemento, a cualquier atributo
de los elementos, a todos los elementos específicos que contienen texto y a
muchas otras variaciones.

XPath a veces puede ser útil al probar servicios web usando XML para enviar
solicitudes y recibir respuestas.

Además, usa una sintaxis de lenguaje muy similar a la que ya conocemos.


La sintaxis es una mezcla de expresiones básicas del lenguaje de
programación y expresiones de ruta similares a Unix (como /libros/autor).
XML como almacenamiento de datos

XPath proporciona un conjunto de

funciones útiles (como count() o

contains() u otras) que nos El nodo raíz (solo uno por documento).
permiten buscar varios fragmentos Nodos de elemento.
de datos dentro del documento.
Nodos de atributos.

XPath ve un documento XML como Nodos de texto.


un árbol de nodos. Este árbol es
Nodos de comentarios.
muy similar a un Modelo de objetos
Procesando nodos de instrucciones.
de documento, es decir, un árbol
Nodos de espacio de nombres.
DOM. Hay siete tipos de nodos en el

modelo de datos XPath:


XML como almacenamiento de datos

En Java, una expresión XPath puede devolver uno de los


siguientes tipos de datos:

1 2 3 4 5
node-set node boolean number string
Representa un Representa un solo Representa el valor Representa un Representa cero o
conjunto de nodos. nodo. Esto puede verdadero o falso. número de coma más caracteres, tal
El conjunto puede estar vacío o puede flotante. Todos los como se define en
estar vacío o puede contener cualquier números en XPath y la especificación
contener cualquier número de nodos XSLT se XML.
número de nodos. secundarios. implementan como
números de punto
flotante; el tipo de
datos entero (o int)
no existe en XPath y
XSLT.
XML como almacenamiento de datos

OPERADOR DESCRIPCIÓN
Selecciona únicamente a los descendientes directos.
/
Selecciona todos los descendientes.
//
Selección del elemento actual.
.
Todos.
*
Prefijo que se antepone al nombre de un atributo.
@
[] Filtro sobre el conjunto de nodos seleccionado.
XML como almacenamiento de datos

T R ATA M I E N TO D E B A S E S D E DATO S X M L

Recorrido, edición, creación


y borrado de nodos
A continuación, se muestra un ejemplo de una aplicación que:

1. Abre un fichero XML.


2. Realiza varias consultas sobre dicho fichero.
3. Elimina un nodo.
4. Crear un nuevo nodo.
5. Guarda los cambios en el fichero.

Ve r
e j e m p l o
TIEMPO ESTIMADO DE LECTURA
10 min

https://drive.google.com/file/d/1oE4kPfUXeAw3viuAMoN6ntA04YU-CNNn/view
XML como almacenamiento de datos

T R ATA M I E N TO D E B A S E S D E DATO S X M L

Tratamiento de excepciones
Cuando se produce un error durante el procesamiento de cualquier expresión
XPath se lanza una excepción de tipo XPathException.

Las propiedades más importantes son:


P R O P I E D A D D E S C R I P C I Ó N
Obtiene una colección de pares clave/valor que proporciona información definida
data
por el usuario adicional sobre la excepción.
Obtiene o establece un vínculo al archivo de ayuda asociado a esta excepción.
helpLink
Obtiene o establece HRESULT, un valor numérico codificado que se asigna a una
hResult excepción específica.

Obtiene la instancia Exception que produjo la excepción actual.


innerException

message Obtiene la descripción de la condición de error para esta excepción.


Devuelve o establece el nombre de la aplicación o del objeto que generó el error.
source
Obtiene una representación de cadena de los marcos inmediatos en la pila de
stackTrace llamadas.
Ve r
Obtiene el método que produjo la excepción actual. e j e m p l o
targetSite
TIEMPO ESTIMADO DE LECTURA
10 min

https://drive.google.com/file/d/1edVcnV-N63h4XQ8cpSesKBmJyvmbvkj2/preview
XML como almacenamiento de datos

Resumen
de la unidad

En este capitulo hemos visto como podemos utilizar como base de datos

un documento, en este caso un fichero XML.

Hemos aprendido el lenguaje de consultas para ficheros XML: XPath. El

cual dispone de diferentes expresiones que nos ayudan a encontrar y

modificar un elemento cualquiera dentro del fichero XML


7.7 Acceso a
ficheros
C O M E N Z A R
Acceso a ficheros

Un programa
N E C E S I TA O B T E N E R I N F O R M AC I Ó N D E S D E U N
O R IGEN O ENVIAR INFO R M ACIÓ N A UN D ESTINO.

Por ejemplo, enviar información a la pantalla o a un fichero u


obtener información desde el teclado o desde un fichero, etc.

LA COMUNICACIÓN ENTRE EL ORIGEN DE LA INFORMACIÓN Y EL DESTINO


SE REALIZA MEDIANTE UN FLUJO (O STREAM) DE INFORMACIÓN.

FLUJO DESDE EL ORIGEN

Origen

Programa

Destino
FLUJO HACIA EL DESTINO
Acceso a ficheros

¿Qué es un flujo?
DEFINICIÓN
Un flujo es un objeto que funciona como intermediario entre el programa y
! el origen o el destino de la información, de este modo el programa lee o
escribe en el flujo sin tener en cuenta a dónde va la información o desde
donde viene y sin importante que tipo de datos está leyendo o escribiendo.

Este nivel de abstracción supone que el programa no tiene que saber


nada de la información ni del tipo de dispositivo, lo que significa que
escribir el programa será mucho más fácil.

Si un programa quiere obtener información desde un origen tiene que


abrir un flujo y leer la información, y si lo que quiere es enviar información
a un destino tendrá que abrir un flujo y escribir la información.
Acceso a ficheros

Algoritmos
PA R A L E E R Y E S C R I B I R D AT O S :

1 2

LEER: ESCRIBIR
• Abrir un flujo desde el origen • Abrir un flujo desde el origen
• Mientras haya información • Mientras haya información
Leer información Escribir información
• Cerrar el flujo • Cerrar el flujo
Acceso a ficheros

Todas las clases relacionadas con flujos


SE ENCUENTRAN EN EL PAQUETE java.io DE LA BIBLIOTECA ESTÁNDAR DE JAVA.
PARA UTILIZAR FLUJOS
import java.io.*;

Las clases de este paquete java.io están divididas en dos grupos


distintos, derivados de la clase Object del paquete java.lang.
Acceso a ficheros

LOS DOS GRUPOS TIENEN CLASES CON INTERFACES CASI IGUALES


Y SE UTILIZAN DE LA MISMA MANERA:

Object

Las clases sombreadas


InputStream Reader
son clases abstractas,
que no permiten que se
Subclases Subclases creen objetos de ella, su
objetivo es proporcionar
miembros comunes que
OutputStream Writer se compartirán por
todas las subclases.
Subclases Subclases
Acceso a ficheros

Clasificación de los flujos:


Representación
Propósito
de la información

• Flujos de bytes • Entrada


• InputStream • InputStream
• OutputStream • Reader
• Flujos de caracteres • Salida
• Reader • OutputStream
• Writer • Writer
• Lectura/Escritura
• RandomAccessFile
Acceso a ficheros

Flujos de Bytes
CON ESTE FLUJO LOS DATOS SE PUEDEN LEER Y
ESCRIBIR DE UN FICHERO BYTE A BYTE, UTILIZANDO
FLUJOS DE LAS CLASES:

1 2

FileOutputStream FileInputStream
Acceso a ficheros

1
FileOutputStream

Los flujos de esta clase permiten escribir bytes en un fichero.


Hereda métodos de OutputStream y proporciona varios constructores:

FileOutputStream (String nombre)


Este constructor abre un flujo de salida hacia el fichero que
especifica nombre.

FileOutputStream (String nombre, boolean añadir)


Este constructor hace lo mismo que el anterior pero
además ofrece la posibilidad de añadir datos a un fichero
existente (añadir = true)

FileOutputStream (File fichero)


Este abre el flujo de salida a partir de un objeto File.

Ver ejemplo
TIEMPO ESTIMADO DE LECTURA
10 min

https://drive.google.com/file/d/1oDkBDLshzdgEsJrJL5WmH5GW4kbgG6gO/preview
Acceso a ficheros

2
FileInputStream

Los flujos de esta clase permiten leer bytes en un fichero.


Hereda métodos de InputStream y proporciona los siguientes constructores:

FileInputStream (String nombre)


Este constructor abre un flujo de entrada desde el fichero
especificado por nombre.

FileInputStream (File nombre)


Este constructor abre un flujo de entrada a partir de un
objeto File.

Ver ejemplo
TIEMPO ESTIMADO DE LECTURA
10 min

https://drive.google.com/file/d/15YoY-asds5xcNzeoPBPYYBapALH4Rgrs/preview
Acceso a ficheros

Flujo de caracteres
LOS STREAMS ORIENTADOS A CARACTERES
MANEJAN CUALQUIER CARÁCTER DEL
CONJUNTO DE CARACTERES UNICODE.

Se utilizan para tratar con el usuario o con archivos


de texto o Web (html).

Reader
CLASES:
Writer
Acceso a ficheros

La clase Reader
ES SIMILAR A Inputstream PERO Reader ESTÁ
ORIENTADA A LEER CARACTERES UNICODE EN
LUGAR DE BYTES.

Las clases que heredan de Reader nos servirán para


obtener información textual como puede ser el teclado
o ficheros de texto.

Los métodos de lectura son muy parecidos a los que


presenta la clase InputStream, aunque retorna caracteres
en lugar de bytes.
Acceso a ficheros

LA CLASE Reader

Tiene seis subclases directas:


BufferedReader Para leer líneas y realizar una lectura eficiente de caracteres.

CharArrayReader Crean streams a partir de un array de caracteres y de Strings


y StringReader respectivamente.

PipedReader Permite sincronizar diferentes threads a través de memoria


para la comunicación de caracteres entre ellos.

InputStreamReader Permite obtener un Reader a partir de cualquier


InputStream y leer caracteres de streams orientados a
bytes. Para leer ficheros de texto se puede usar la clase
FileReader que hereda de InputStreamReader.

BufferedReader Permite crear filtros.


Acceso a ficheros

Para mostrar un
fichero por pantalla BufferedReader lectorBuffer = null;
int NUM_ITEMS = 1;
Ejemplo
try {
int leidos;
FileReader lectorFichero = new FileReader("ruta al " + "fichero");
BufferedReader lectorBuffer = new BufferedReader(lectorFichero);
char [] buffer = new char[NUM_ITEMS];
do {
leidos = lectorBuffer.read(buffer);
System.out.print(buffer);
} while (leidos == NUM_ITEMS);
}
catch (IOException ex) {
System.err.println("Se ha producido un error de lectura");
}
Acceso a ficheros

Para leer caracteres


del teclado public static String leerString() {
InputStreamReader tecladoReader = new InputStreamReader(System.in);
Ejemplo BufferedReader lectorCadenas = new BufferedReader(tecladoReader);
String resultado = "";

try{
System.out.println("Escribe algo...");
resultado = lectorCadenas.readLine(); // BufferedReader //permite leer
} // hasta el fin de //linea
catch(IOException e){
System.err.println("Se ha producido un error de lectura");
System.exit(-1);
}
return resultado;
}

Llamando a la función de la siguiente forma: System.out.println(leerString());


Acceso a ficheros

La clase Writer
ES LA VERSIÓN ORIENTADA A CARACTERES DE Outputstream.

CLASES QUE HEREDAN:

BufferedWriter. Permite realizar escrituras a través de un buffer.

CharArrayWriter y StringWriter. Con ellas podemos escribir sobre arrays


de caracteres o Strings.

PrintWriter. Parecida a PrintStream pero orientada a streams de caracteres.

FilterWriter. Permite crear filtros.

PipedWriter. Permite crear un camino (pipe) entre dos threads para la


comunicación sincronizada de caracteres.

OuputStreamWriter. Es un filtro de OutputStream para escribir caracteres


sobre él igual que InputStreamReader con InputStream.
Acceso a ficheros

FileImputStream
LineNumberInputStream
Jerarquía PipedInStream
DataInputStream

de clases FilterInputStream
BufferedInputStream
InmputStream ByteArrayInputStream
PushbackInputStream
SequenceInputStream

StringBufferInputStream

ObjectInputStream

FileOutputStream

PipedOutputStream DataOutputStream

OutputStream FilterOutputStream BufferedOutputStream

ByteArrayOutputStream PushbackOutputStream

ObjectOutputStream
Acceso a ficheros

Jerarquía BufferedReader LineNumberReader

de clases CharArrayReader

InputStreamReader FileReader

Reader FilterReader PushbackReader

PipedReader

BufferedWriter
StringReader

CharArrayWriter

OutputStreamWriter FileWriter

FilterWriter
Writer
PipedWriter

StringWriter

PrintWriter
Acceso a ficheros

La clase File
PERMITE EXAMINAR Y MANIPULAR ARCHIVOS Y DIRECTORIOS.

Proporciona una representación abstracta de ficheros


y directorios.
Además, proporciona un constructor que crea un
objeto File a partir de un nombre de fichero más su
ruta de acceso.

public File(String ruta_completa)


Acceso a ficheros

Ejemplo
File fichero = new File("proyecto\\texto.txt");
System.out.println("Nombre del fichero: " + fichero.getName());
System.out.println("Directorio padre: " + fichero.getParent());
System.out.println("Ruta relativa: " + fichero.getPath());
System.out.println("Ruta absoluta: " + fichero.getAbsolutePath());

El resultado al ejecutar el código será:

Nombre del fichero: texto.txt


Directorio padre: proyecto
Ruta relativa: proyecto\texto.txt
Ruta absoluta: C:\java\proyecto.txt
Acceso a ficheros

Cómo se crean y
eliminan ficheros

VER VIDEO
https://player.vimeo.com/video/728033306?h=3ae1bd0a
79

https://player.vimeo.com/video/728033306?h=3ae1bd0a79
Acceso a ficheros

SE ACCEDE A ELLOS
java.lang.System

La entrada y salida estándar


SON FLUJOS DE DATOS QUE ACTÚAN COMO CANALES DE COMUNICACIÓN Y
PERMITEN LA INTERACCIÓN ENTRE UN PROGRAMA Y SU ENTORNO EN EL SISTEMA.

Como se ha podido observar en numerosos ejemplos de unidades anteriores, la


entrada/salida estándar (normalmente el teclado y la pantalla, respectivamente) se
definen mediante los objetos System.in y System.out.

La clase System contiene la instancia in de la clase InputStream que representa


al teclado o flujo de entrada estándar, y el miembro out que es un objeto de la
clase PrintStream, que imprime el texto en la pantalla (la salida estándar).

Para leer un carácter solamente tenemos que llamar a la función read desde
System.in.

try{
System.in.read();
}catch (IOException ex) { }
Acceso a ficheros

La clase java.util.Scanner
PERMITE LEER DATOS DESDE UN FLUJO DE ENTRADA, DESDE UN
FICHERO (FILE) O DE UN string.

Un objeto de la clase Scanner es un lector de texto que puede traducir lo leído.

Ejemplo
Scanner leer = new Scanner (System.in);
System.out.print("Cadena de caracteres: ");
String str = leer.next();
System.out.print("Valor entero: ");
Este código lee un
int dato = leer.nextInt(); String y un int de
leer.close(); la entrada estándar.
Acceso a ficheros

La clase Scanner
NOS FACILITA MUCHO LA TAREA DE OBTENCIÓN
DE DATOS DESDE DIFERENTES FUENTES.

Pr i n c i p a l e s u s o s :

1 Obtener datos desde el teclado.

2 Obtener datos desde un fichero.


Acceso a ficheros

public static void main(String[] args) {


String variableString;
Ejemplo
Scanner entrada = new Scanner(System.in);
System.out.print("Ingrese un texto: ");
variableString = entrada.next();
System.out.println("Texto ingresado: " + variableString);
entrada.close();
}

En el código anterior se declara una instancia de Scanner, pasando como


parámetro un objeto InputStream, gracias al método in de la clase System.

En un paso posterior, se imprime un mensaje para indicar al usuario que


debe introducir un texto. Este texto es leído utilizando el método next().

Después, se vuelve a imprimir en consola, la palabra que anteriormente ha


introducido el usuario.

Para finalizar se cierra el flujo llamando al método close().


Acceso a ficheros

Lectura de ficheros con la clase Scanner


Como decíamos anteriormente, la clase Scanner también puede ser utilizada para leer ficheros.

Ejemplo
try {
Scanner entrada = new Scanner(new File("C:\\CarpetaEjemplos\\numero.txt"));
while (entrada.hasNextLong()) {
System.out.println("numero: " + entrada.nextLong());
}
entrada.close();
} catch (FileNotFoundException e) {
System.out.println("Error al leer el fichero numero.txt");
}

En este caso, se ha pasado como parámetro de entrada al constructor de Scanner un


fichero. Con ese objeto, se ha iterado con un while, para ir leyendo e imprimiendo por
consola todos los números que estén en el archivo.
Acceso a ficheros

HACIENDO USO DEL

Objeto System.out
PODEMOS REPRESENTAR EN PANTALLA CADENAS DE
CARACTERES, O CUALQUIER OTRO TIPO DE DATO EN
FORMA DE TEXTO REALIZÁNDOSE EL “CASTING”
IMPLÍCITO EN CASO DE SER NECESARIO, O UTILIZANDO
LA REPRESENTACIÓN TEXTUAL DE UN OBJETO.
Acceso a ficheros

Consideremos la siguiente clase:


Ejemplo
public class MiObjeto {

String atr1 = "este es mi primer atributo";


String atr2 = "este es mi segundo atributo";
String atr3 = "este es mi tercer atributo";

@Override
public String toString() {
return "MiObjeto [atr1=" + atr1 + ", atr2=" + atr2 + ",
atr3=" + atr3 + "]";
}
}

Como se puede ver, se ha implementado el método “toString()”, este método


determinará la representación textual que ha de tener el objeto.
Acceso a ficheros

Si realizamos la siguiente llamada:


Ejemplo
MiObjeto obj = new MiObjeto();

System.out.print(obj);

Si realizamos la siguiente llamada:

MiObjeto [atr1=este es mi primer atributo, atr2=este es mi segundo


atributo, atr3=este es mi tercer atributo]

En resumen, haciendo uso de la salida estándar por pantalla, se ha representado


en esta el objeto creado en forma de texto.
7.8 Serialización de
ficheros
C O M E N Z A R
Serialización de ficheros

Formas de acceso a un fichero


MODOS BÁSICOS:

1 SECUENCIAL
En el modo secuencial la información del archivo es
una secuencia de bytes (o caracteres) de manera que
para acceder al byte (o carácter) i-ésimo se ha de
haber accedido anteriormente a los i-1 anteriores.

2 ACCESO DIRECTO
El modo de acceso directo nos permite acceder
directamente a la información del byte i-ésimo. Un
ejemplo muy conocido de acceso directo lo tenemos
con los vectores (arrays).
Serialización de ficheros

Operaciones de
lectura/escritura
En el ejemplo se van a utilizar las clases FileWriter
y FileReader.

Se trata de una pequeña aplicación que primero añadirá


100 letras a un fichero de entrada y posteriormente, leerá
el fichero para contar en número de vocales que hay en él.

public static void main(String[] args) {


LecturaEscritura app = new LecturaEscritura();
File fichero = new File("C:\\CarpetaEjemplos\\archivo1.txt");
app.escribirEnFichero(fichero);
app.contarVocalesEnFichero(fichero);
}

public void escribirEnFichero(File fichero) {


try {
FileWriter writer = new FileWriter(fichero);
for (int i = 0; i < 100; i++) {
writer.write(generarLetra());
}
writer.close();
} catch (IOException e) {
System.err.println("Algo ha ido mal al escribir en el fichero :-(");
}
}
System.err.println("Algo ha ido mal al escribir en el fichero :-(");
Serialización de ficheros }
}

public void contarVocalesEnFichero(File fichero) {


try {
int vocales = 0;
FileReader reader = new FileReader(fichero);
En el método escribirEnFichero() se crea un int c = reader.read();

FileWriter y utilizamos su método write() para ir while (c != -1) {


char ch = (char) c;
añadido hasta 100 letras que generamos de manera if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {

aleatoria utilizando el método generarLetra(). }


vocales++;

c = reader.read();
}
En el método se crea un FileReader que dispone reader.close();

de un método read() que nos irá devolviendo uno System.out.println("Numero de vocales encontradas: " + vocales);
} catch (IOException e) {
a uno los caracteres del fichero hasta que llegue al System.err.println("Algo ha ido mal al contar las vocales :-(");

final que nos devolverá un -1.


}
}

public static char generarLetra() {


En ambos métodos, y muy importante, se llama Random r = new Random();
return (char) (r.nextInt(26) + 'a');
al método close() que cerrará el flujo de datos. }
https://player.vimeo.com/video/728033330?h=99a45c36
48

https://player.vimeo.com/video/728033330?h=99a45c3648
Serialización de ficheros

Para los ficheros binarios


SE REALIZAN LAS MISMAS OPERACIONES PERO UTILIZAMOS
Inputstream Y Outputstream EN LUGAR DE Reader Y Writer.

InputStream
Serialización de ficheros

Para los ficheros binarios


SE REALIZAN LAS MISMAS OPERACIONES PERO UTILIZAMOS
Inputstream Y Outputstream EN LUGAR DE Reader Y Writer.

InputStream
Es una clase abstracta que es superclase de todas las que
representan un flujo en el que un destino lee bytes de un origen.
El método mas importante de esta clase es read. Una de las
formas que presenta este método es:
public int read() throws IOException
El método read lee bytes individuales de un flujo de entrada,
devuelve un entero (int) correspondiente al valor ADCII del
carácter leído, o bien -1 cuando en un intento de leer datos se
alcanza el final del flujo (no hay mas datos).
Serialización de ficheros

Para los ficheros binarios


SE REALIZAN LAS MISMAS OPERACIONES PERO UTILIZAMOS
Inputstream Y Outputstream EN LUGAR DE Reader Y Writer.

InputStream
Ejemplo:
Supongamos que tenemos definido un objeto flujoE (flujo de
OutputStream entrada) de alguna subclase de InputStream, el siguiente
código lee un byte del origen vinculado con flujoE:
int n;
n = flujoE.read();
Serialización de ficheros

Para los ficheros binarios


SE REALIZAN LAS MISMAS OPERACIONES PERO UTILIZAMOS
Inputstream Y Outputstream EN LUGAR DE Reader Y Writer.

InputStream

Es una clase abstracta que es superclase de todas las clases que


OutputStream representan un flujo en el que un origen escribe bytes en un destino.
Cuando un programa define un flujo de salida, el programa es origen
de ese flujo de bytes.
El método mas importante de esta clase es write. Una de las formas
que presenta este método es:
public voice write(int b) throws IOException
El método write escribe el byte especificado en un flujo de salida. Su
parámetro es de tipo int, por lo que escribe el valor correspondiente
a 8 bits menos significativos y el resto se ignoran.
Serialización de ficheros

Para los ficheros binarios


SE REALIZAN LAS MISMAS OPERACIONES PERO UTILIZAMOS
Inputstream Y Outputstream EN LUGAR DE Reader Y Writer.

InputStream

Ejemplo:
OutputStream
Si tenemos definido un objeto flujoS (flujo de salida) de alguna
subclase de OutputStream, este código escribirá el byte especificado
en el destino vinculado con flujoS.
int n:
//…
flujos.write(n);
Serialización de ficheros

Serialización
CUANDO QUEREMOS TRANSMITIR ESTRUCTURAS
MAS COMPLEJAS

A través de este mecanismo se pueden convertir los


objetos en secuencias de bytes que sí se pueden transmitir
a través de flujos.

DEFINICIÓN
La serialización incorpora información sobre la clase a
! la que pertenecen los objetos y del estado interno de
los mismos, así es sencillo verificar si la recuperación del
objeto serializado se ha realizado de manera correcta.
Serialización de ficheros

La serialización y deserialización
SE REALIZA A TRAVÉS DE DOS CLASES DE FLUJOS O Streams:

Como medida de seguridad, sólo permite


Con ObjectOuptutStream podremos serializar un serializar objetos de clases que implementen
objeto por medio del método write(Object obj);, la interfaz Serializable, ya que al ser un
puesto que su argumento es de tipo Object, admite objeto serializado se almacena en el disco y
se transmite por la red y por tanto es posible
cualquier objeto. tener acceso a sus datos en remoto.

Con ObjectInputStream podremos recuperar los


objetos que han sido serializados, a través del método
readObject();, que devuelve un objeto de la clase
Object al que tendremos que realizar un casting a la
clase concreta a la que pertenezca; para esto
realizaremos una comprobación con el operador
instanceof.
Serialización de ficheros

Para hacer un objeto serializable


ÚNICAMENTE HAY QUE INDICAR EN SU CABECERA QUE
IMPLEMENTA LA INTERFAZ serializable (YA QUE ESTA
NO DISPONE DE NINGÚN MÉTODO).

La instancia de ObjectOutputStream se construye sobre objetos de la


clase OutputStream y ObjectInputStream sobre objetos de la clase
InputStream.

No se deben serializar objetos que tengan recursos abiertos como


ficheros o conexiones de red.
Serialización de ficheros

Vamos a ver como guardar en fichero el conjunto de clientes que maneja una
aplicación de gestión de clientes para poder recuperarlo al reiniciar la aplicación:
Ejemplo
Cliente[] clientes; //La clase cliente implementa Serializable
...
try {
FileOutputStream escritor = new FileOutputStream("clientes.dat");
ObjectOutputStream oos = new ObjectOutputStream(escritor);
oos.writeObject(clientes); // Serialización del objeto clientes
oos.close(); // Cierra el stream y hace flush
} catch (IOException ex) {
// Se ha producido un error al serializar
}
Serialización de ficheros

Para cargar los datos de dicho fichero debemos hacer lo siguiente:

Ejemplo Cliente[] clientes = null;


try {
FileInputStream lector = new
FileInputStream("clientes.dat");
ObjectInputStream oos = new ObjectInputStream(lector);
clientes = (Cliente[]) oos.readObject();
oos.close();
} catch (IOException ex) {
// Error al leer fichero
}
catch (ClassNotFoundException ex) {
// Clase no encontrada
}
hemos
terminado
¡EXCELENTE TRABAJO!

También podría gustarte