Вы находитесь на странице: 1из 48

Tema 3

Entrada/Salida. Serializacin

J. Gutirrez

Departament d'Informtica
Universitat de Valncia

Programacin (GIET).
Curso 12/13

J. Gutirrez, Tema 3

Curso 12/13

1/95

Curso 12/13

2/95

ndice
1 Objetivos
2 Introduccin
3 Entrada/Salida
Entrada orientada a bytes
Salida orientada a bytes
Entrada orientada a caracteres
Salida orientada a caracteres
La clase Scanner

4 Serializacin
Introduccin
Flujos para lectura y escritura de objetos
Implementando Serializable
Implementando Externalizable

5 Material adicional

J. Gutirrez, Tema 3

Objetivos

ndice

Objetivos

Introduccin

Entrada/Salida

Serializacin

Material adicional

J. Gutirrez, Tema 3

Curso 12/13

3/95

Objetivos

Objetivos I

2
3
4

Clasicar la categora (entrada/salida, orientada a bytes/orientada a


caracteres, bajo nivel/ltrada) a la que pertenece una clase.
Enumerar las clases principales de una categora dada.
Describir para qu se utiliza el patrn decorador.
Construir aplicaciones que usen correctamente las clases de
entrada/salida.
Enumerar las interfaces que deben implementar los objetos que pueden
ser serializados.
Describir los pasos necesarios para realizar la serializacin y la
recuperacin.

J. Gutirrez, Tema 3

Curso 12/13

4/95

Objetivos

Objetivos II

9
10

Construir clases cuyas instancias puedan ser serializadas segn las


especicaciones dadas.
Comparar la serializacin mediante Serializable y mediante
Externalizable.
Elegir y justicar la mejor alternativa para serializar un objeto.
Construir aplicaciones que usen correctamente la serializacin.

J. Gutirrez, Tema 3

Curso 12/13

5/95

Curso 12/13

6/95

Introduccin

ndice

Objetivos

Introduccin

Entrada/Salida

Serializacin

Material adicional

J. Gutirrez, Tema 3

Introduccin

Por qu entrada/salida?

Almacenamiento/Recuperacin de informacin

Una aplicacin puede obtener o guardar datos en un chero


Comunicacin entre mquinas

La comunicacin entre mquinas se realiza recibiendo o enviando


informacin (usando la entrada/salida).
Estas dos situaciones son similares: los datos uyen desde un lugar a otro
(slo cambia la fuente y el destino).

J. Gutirrez, Tema 3

Curso 12/13

7/95

Introduccin

Por qu serializacin?

La serializacin es el proceso de transformacin de un objeto (o


conjunto de objetos) en una secuencia de bits. Se puede aplicar en dos
situaciones:
1

: Qu ocurre con un objeto cuando naliza la


mquina virtual sobre la que existe? Se destruye. Se puede conseguir la
persistencia de un objeto guardndolo para ser recuperado posteriormente.

: el objeto serializado se puede


enviar a otra mquina virtual donde puede ser reconstruido.

Persistencia de objetos

Paso de objetos a otra mquina virtual

J. Gutirrez, Tema 3

Curso 12/13

8/95

Entrada/Salida

ndice

Objetivos

Introduccin

Entrada/Salida

Serializacin

Material adicional

J. Gutirrez, Tema 3

Curso 12/13

9/95

Entrada/Salida

Comparacin de la E/S en Java con la de C++

La E/S en Java es diferente de la E/S de C++:


En C++ las clases de salida a pantalla y entrada de teclado estn
declaradas en el archivo de cabecera iostream.h . Las clases para el
trabajo con cheros estn declaradas en el archivo de cabecera
fstream.h .
En Java la mayora de clases para la E/S estn denidas en el paquete
java.io

En C++ la salida de un mensaje a pantalla se puede realizar utilizando


el objeto cout del siguiente modo:
cout << "Introduce un valor: ";

Lo equivalente en en Java se puede realizar utilizando el atributo


esttico out declarado como pblico en la clase System :
System.out.println("Introduce un valor: ");

J. Gutirrez, Tema 3

Curso 12/13

10/95

Entrada/Salida

Comparacin de la E/S en Java con la de C++

En Java la entrada por teclado requiere unas cuantas ms lneas de cdigo


que el equivalente en C++.
import java . io .*;
class EntradaConsola {

public static void main ( String [] args ) {


try {
System . out . println ( " Introduce texto ");
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in )) ;
String cad = br . readLine () ;
System . out . println ( cad );
} catch ( IOException e){
System . out . println ( " Error de E/S ");
}
}

J. Gutirrez, Tema 3

Curso 12/13

11/95

Entrada/Salida

Flujos (streams)

Un ujo es una abstraccin de cualquier secuencia de datos que va


desde una fuente (o productor de datos) hacia un destino (o
consumidor de datos).
Se puede interpretar como una serie de datos circulando a travs de
un canal que une a la fuente y al destino.

J. Gutirrez, Tema 3

Curso 12/13

12/95

Entrada/Salida

Flujo de entrada (Input stream)


Programa

00010001 11110001 01011010

Fuente de datos

Fichero
Memoria
Red

FilterInputStream

FileInputStream

Flujo de salida (Output stream)


Programa

00010001 11110001 01011010

Destino de datos

Fichero
Memoria
Red

FilterInputStream

FileInputStream
J. Gutirrez, Tema 3

Curso 12/13

13/95

Entrada/Salida

Algunos ejemplos de fuentes o destinos de datos a los que se pueden


asociar ujos de E/S:
A la entrada estndar System.in , a la salida estndar System.out ,
a la salida de error estndar System.err .
Fichero binarios o cheros de texto.
Conexiones de red
A bloques de memoria (lectura o escritura de datos en la memoria).

J. Gutirrez, Tema 3

Curso 12/13

14/95

Entrada/Salida

Una taxonoma (clasicacin) de las clases de entrada/salida:


Clases que representan ujos de entrada
I

Orientados a bytes
F De bajo nivel
F Filtrados

Orientados a caracteres
F De bajo nivel
F Filtrados

Clases que representan ujos de salida


I

Orientados a bytes
F De bajo nivel
F Filtrados

Orientados a caracteres
F De bajo nivel
F Filtrados

J. Gutirrez, Tema 3

Curso 12/13

15/95

Entrada/Salida

Los ujos de bajo nivel1 orientados a bytes ofrecen funcionalidad


bsica para lectura o escritura de bytes.
Los ujos de bajo nivel orientados a caracteres ofrecen
funcionalidad bsica para lectura o escritura de caracteres (con
diferentes codicaciones).
Los ujos ltrados orientados a bytes ofrecen funcionalidades
adicionales (por ejemplo utilizando un buer intermedio o permitiendo
el trabajo con tipos primitivos) para la lectura o escritura orientada a
bytes.
Los ujos ltrados orientados a caracteres ofrecen funcionalidades
adicionales para la lectura o escritura orientada a caracteres.

A estos se les llama

node streams.

J. Gutirrez, Tema 3

Curso 12/13

16/95

Entrada/Salida

Las clases base (declaradas como abstractas) del paquete java.io son:
Para ujos orientados a bytes:
I
I

De entrada: java.io.InputStream
De salida: java.io.OutputStream

Para ujos orientados a caracteres:


I
I

De entrada: java.io.Reader
De salida: java.io.Writer

J. Gutirrez, Tema 3

Curso 12/13

Entrada/Salida

17/95

Entrada orientada a bytes

ndice

3 Entrada/Salida

Entrada orientada a bytes


Salida orientada a bytes
Entrada orientada a caracteres
Salida orientada a caracteres
La clase Scanner

J. Gutirrez, Tema 3

Curso 12/13

18/95

Entrada/Salida

Entrada orientada a bytes

Los ujos de lectura extienden a la clase java.io.InputStream


En esta clase se dene el mtodo abstracto:
public abstract int read()throws IOException

que lee el siguiente byte y lo devuelve como un int en el rango 0 a


255. Si se ha llegado al nal del ujo devuelve un -1.
El mtodo read() bloquea la ejecucin del programa hasta que: el
siguiente dato est disponible para ser ledo, se llega al nal del ujo o
se lanza una excepcin.
Puesto que es abstracto cada subclase debe proporcionar una
implementacin de este mtodo.

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

19/95

Entrada orientada a bytes

Algunas clases que representan ujos de entrada de bajo nivel en java.io

Hay varias clases que representan ujos de entrada de bajo nivel y que
extienden a InputStream .
Cada clase representa un ujo asociado a la fuente donde estn los datos:
ByteArrayInputStream
FileInputStream

Permite leer bytes de un bloque de memoria.

Permite leer bytes de un chero.

Permite leer bytes de datos desde dos o ms ujos


de bajo nivel, continuando con el siguiente ujo al nalizar la lectura de
cada uno de ellos.
SequenceInputStream

J. Gutirrez, Tema 3

Curso 12/13

20/95

Entrada/Salida

Entrada orientada a bytes

La jerarqua que siguen estas clases es:

abstract

InputStream

ByteArrayInputStream

FileInputStream

J. Gutirrez, Tema 3

Entrada/Salida

SequenceInputStream

Curso 12/13

21/95

Entrada orientada a bytes

Ejemplo: uso de ujo de entrada de bajo nivel orientado a bytes


import java . io .*;
public class InputDemo {
public static void main ( String [] args ) {
int dato ;
try {
// Se supone que se pasa el nombre del fichero a
// mostrar como un argumento al programa
InputStream entrada = new FileInputStream ( args [0]) ;
while ( ( dato = entrada . read () ) != -1 )
System . out . print ( dato );
System . out . println () ;

entrada . close () ;
} catch ( IOException e){
System . out . println ( " Error leyendo del fichero " + args [0]) ;
}

Esta no es la forma ms eciente de mostrar el contenido de un chero (es


lento) pero sirve para ilustrar la utilizacin de los ujos de entrada de bajo
nivel.
J. Gutirrez, Tema 3

Curso 12/13

22/95

Entrada/Salida

Entrada orientada a bytes

Los ujos de bajo nivel permiten leer bytes pero su exibilidad es


limitada.
Qu ocurre si deseamos leer un entero?, o un double?, o ...?.
Los ujos ltrados aaden funcionalidad (usando un buer,
permitiendo la lectura de tipos primitivos, etc) a un ujo
Los ujos ltrados de entrada extienden a la clase
FilterInputStream que a su vez extiende a la clase InputStream .
Para crear un ujo ltrado hay que disponer en ltima instancia de un
ujo de bajo nivel. Por ejemplo: leer enteros de memoria, leer enteros
de un chero,...

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

23/95

Entrada orientada a bytes

Las clases que se denen en el paquete java.io para entrada orientada a


bytes mediante ujos ltrados son:
Lee bloques de bytes y los almacena en un buer
para mejorar la eciencia.
BufferedInputStream

DataInputStream Lee tipos de datos primitivos, tales


, double e incluso permite leer lneas de texto.
LineNumberInputStream

que se est leyendo.

como int , float

Mantiene un contador sobre el nmero de lnea

Aade la capacidad de volver a colocar un byte (o


array de bytes) ya ledo otra vez en el ujo.
PushBackInputStream

En otros paquetes (en java.security , java.util , javax.crypto ,


java.util.zip ) se denen ms ujos de entrada ltrados.
J. Gutirrez, Tema 3

Curso 12/13

24/95

Entrada/Salida

Entrada orientada a bytes

La jerarqua que siguen estas clases es:

abstract

interface

InputStream

DataInput

FilterInputStream

BufferedInputStream

LineNumberInputStream

DataInputStream

PushBackInputStream

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

25/95

Entrada orientada a bytes

Como se puede ver en el diagrama anterior, estas clases heredan de la


clase FilterInputStream
El constructor de esta clase admite un ujo de entrada:
protected FilterInputStream(InputStream in)

que es utilizado como fuente de datos (la lectura se realiza a travs de


ste).
La clase FilterInputStream simplemente sobreescribe todos los
mtodos de InputStream con versiones que pasan las peticiones al
ujo de entrada pasado en el constructor.
Las subclases de FilterInputStream pueden ocultar algunos de
estos mtodos y pueden proporcionar mtodos o atributos adicionales.

J. Gutirrez, Tema 3

Curso 12/13

26/95

Entrada/Salida

Entrada orientada a bytes

Esta solucin se conoce como patrn decorador y pertenece al grupo de


patrones estructurales.
Qu es un patrn?

Un patrn de diseo es una solucin que aparece frecuentemente en


problemas de diseo de aplicaciones.
Un patrn afronta un problema habitual de diseo que aparece en
situaciones especcas y presenta una solucin a l.
Un patrn identica abstracciones que estn por encima del nivel de
clases aisladas, instancias o de componentes.

Cual es la ventaja de utilizar el patrn decorador? Que se evita la


proliferacin de clases.
Cmo? Combinando los ujos para obtener la funcionalidad buscada sin
necesidad de crear nuevas clases.
J. Gutirrez, Tema 3

Curso 12/13

Entrada/Salida

27/95

Entrada orientada a bytes

Tiene un atributo del tipo

InputStream

FilterInputStream

ByteArrayInputStream

FileInputStream

Clases concretas

DataInputStream

BufferedInputStream

Clases que decoran

Qu se puede decorar? cualquier clase que sea del tipo InputStream.

J. Gutirrez, Tema 3

Curso 12/13

28/95

Entrada/Salida

Entrada orientada a bytes

fichero.bin
AF 00 CB 7A 23 09

FileInputStream extends InputStream


FileInputStream(String nomFich){...}
int read(){...}

new FileInputStream( "fichero.bin");

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

29/95

Entrada orientada a bytes

fichero.bin
FilterInputStream extends InputStream
InputStream in;

AF 00 CB 7A 23 09

FilterInputStream(InputStream en){
in = en;
}
int read(){
return in.read();
}

DataInputStream extends FilterInputStream ...


DataInputStream(InputStream en){
super(en);

FileInputStream extends InputStream


FileInputStream(String nomFich){...}
int read(){...}

DataInputStream din =
new DataInputStream(
new FileInputStream(
"fichero.bin"));

}
int readInt(){
byte b = read();
byte b2 = read();
byte b3 = read();
byte b4 = read();
}

...

J. Gutirrez, Tema 3

Curso 12/13

30/95

Entrada/Salida

Entrada orientada a bytes

fichero.bin
FilterInputStream extends InputStream
InputStream in;

AF 00 CB 7A 23 09

FilterInputStream(InputStream en){
in = en;
}
FileInputStream extends InputStream

int read(){
return in.read();
}

FileInputStream(String nomFich){...}
int read(){...}

DataInputStream extends FilterInputStream ...


DataInputStream(InputStream en){
super(en);

DataInputStream din =
new DataInputStream(
new FileInputStream(
"fichero.bin"));

}
int i = din.readInt();

int readInt(){
byte b = read();
byte b2 = read();
byte b3 = read();
byte b4 = read();
}

...

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

31/95

Entrada orientada a bytes

Ejemplo: uso de un ujo de entrada ltrado orientado a bytes I


import java . io .*;
class DemoDataInputStream {
public static void main ( String [] args ) {
try {
// Suponemos que los datos estan en el fichero datos . bin
DataInputStream in = new DataInputStream ( new FileInputStream (" datos . bin ")) ;

// Si no sabemos cuantos datos hay leemos hasta que se produzca una excepcion
boolean fin = false ;
double suma = 0;
while (! fin ){
try {
int dato = in . readInt () ;
suma += dato ;
} catch ( EOFException ex ){
fin = true ;
}
}
in . close () ;
System . out . println ( " La suma de los enteros del fichero es : " : suma ) ;
} catch ( IOException ex ) {
System . err . println ( " Error al leer el fichero " );
}

J. Gutirrez, Tema 3

Curso 12/13

32/95

Entrada/Salida

Entrada orientada a bytes

Ejemplo: uso de un ujo de entrada ltrado orientado a bytes II

J. Gutirrez, Tema 3

Curso 12/13

Entrada/Salida

33/95

Salida orientada a bytes

ndice

3 Entrada/Salida

Entrada orientada a bytes


Salida orientada a bytes
Entrada orientada a caracteres
Salida orientada a caracteres
La clase Scanner

J. Gutirrez, Tema 3

Curso 12/13

34/95

Entrada/Salida

Salida orientada a bytes

Los ujos de salida extienden a la clase OutputStream .


Esta clase dene el mtodo abstracto:
public abstract void write(int b)throws IOException

que escribe un byte en este ujo de salida. El byte que se escribe se


obtiene como los 8 bits de ms bajo orden del argumento b . Los
restantes 24 bits de b se desechan.
Cada subclase debe proporcionar una implementacin de este mtodo.
El paquete java.io proporciona unos cuantos ujos de salida y hay
que saber cual es el apropiado para realizar de forma efectiva la
escritura.

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

35/95

Salida orientada a bytes

Las siguientes clases representan ujos de salida de bajo nivel:


ByteArrayOutputStream
FileOutputStream

Escribe bytes en un bloque de memoria.

Escribe bytes a un chero.

J. Gutirrez, Tema 3

Curso 12/13

36/95

Entrada/Salida

Salida orientada a bytes

La jerarqua que siguen estas clases de salida de bajo nivel orientadas a


bytes es:

abstract

OutputStream

ByteArrayOutputStream

J. Gutirrez, Tema 3

Entrada/Salida

FileOutputStream

Curso 12/13

37/95

Salida orientada a bytes

Ejemplo: uso de un ujo de salida de bajo nivel orientado a bytes


import java . io .*;
public class OutputDemo {
public static void main ( String [] args ) {
int dato ;
try {
// Se supone que se pasa el nombre del fichero a
// crear como un argumento al programa
OutputStream salida = new FileOutputStream ( args [0]) ;
String s = " Esta es una cadena de prueba " ;
byte [] bytes = s. getBytes () ;
for ( int i =0; i < bytes . length ; i ++)
salida . write ( bytes [ i ]) ;
salida . close () ;

} catch ( IOException e){


System . out . println ( " Error escribiendo en el fichero " + args [0]) ;
}

J. Gutirrez, Tema 3

Curso 12/13

38/95

Entrada/Salida

Salida orientada a bytes

Las clases de salida tambin utilizan el patrn decorador mediante la


clase FilterOutputStream y sus subclases.
El objetivo es el mismo que anteriormente: aadir una determinada
funcionalidad.
Las clases que se denen en el paquete java.io para salida
mediante ujos ltrados se muestran en la siguiente tabla.

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

39/95

Salida orientada a bytes

Esta clase implementa un ujo de salida con


buer, de forma que una aplicacin puede escribir bytes en el ujo de salida
subyacente sin que necesariamente se produzcan llamadas para que se
escriba cada byte (se almacenan en el buer para ser escritos en bloque).
BufferedOutputStream

Permite escribir datos primitivos en un ujo de salida.


Los datos se pueden leer usando DataInputStream .
DataOutputStream

Aade la capacidad de escribir representaciones de diversos


datos de forma conveniente. Los mtodos de esta clase no lanzan una
excepcin del tipo IOException , en su lugar establecen una bandera
interna que puede ser consultada mediante el mtodo checkError() .
La salida estndar (a la que se puede acceder a travs del atributo esttico
out de la clases System ) es de este tipo.
PrintStream

J. Gutirrez, Tema 3

Curso 12/13

40/95

Entrada/Salida

Salida orientada a bytes

La jerarqua que siguen estas clases ltradas orientadas a bytes es:

abstract

interface

OutputStream

DataOutput

FilterOutputStream

BufferedOutputStream

DataOutputStream

PrintStream

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

41/95

Salida orientada a bytes

Ejemplo: uso de un ujo de salida ltrado orientado a bytes


import java . io .*;
class DemoDataOutputInputStream {
public static void main ( String [] args ) {
// Primero se escriben datos de diverso tipo a un fichero
try {
DataOutputStream out = new DataOutputStream (
new FileOutputStream ( " borrame . bin " ));
out . writeChar ( 'A ');
out . writeBoolean ( true );
out . writeInt (256) ;
out . close () ;
} catch ( IOException e) {};
// A continuacin se leen del fichero y se muestran
try {
DataInputStream in = new DataInputStream (
new FileInputStream (" borrame . bin ") );
System . out . println ( in . readChar () );
System . out . println ( in . readBoolean () );
System . out . println ( in . readInt () ) ;
in . close () ;
} catch ( IOException e) {};
}

J. Gutirrez, Tema 3

Curso 12/13

42/95

Entrada/Salida

Entrada orientada a caracteres

ndice

3 Entrada/Salida

Entrada orientada a bytes


Salida orientada a bytes
Entrada orientada a caracteres
Salida orientada a caracteres
La clase Scanner

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

43/95

Entrada orientada a caracteres

Los ujos vistos anteriormente se pueden utilizar para leer y escribir


texto adems de bytes y tipos primitivos de datos.
Sin embargo, para trabajar con texto es mejor utilizar las clases
derivadas de Reader y Writer .
Estas clases fueron introducidas a partir de la versin 1.1 del JDK para
dar soporte a ujos que trabajan con codicacin Unicode.
La clase Reader tiene los mismos mtodos que InputStream salvo
que los distintos mtodos read() trabajan con 2 bytes en lugar de
un byte.
La clase Writer tiene los mismos mtodos que OutputStream
salvo que los distintos mtodos write() trabajan como en el caso
anterior con 2 bytes.

J. Gutirrez, Tema 3

Curso 12/13

44/95

Entrada/Salida

Entrada orientada a caracteres

Codicacin de caracteres

Un sistema de codicacin es una tabla en la que se especica el


nmero correspondiente a cada carcter.
El problema es que dos sistemas de codicacin pueden asignar un
mismo nmero a dos caracteres o usar diferentes nmeros para el
mismo carcter. O que un determinado carcter no exista en una
determinada codicacin (por ejemplo US-ASCII no soporta los
acentos).
Por tanto existe el peligro de que los datos se corrompan al pasar de
un sistema de codicacin a otro.
Unicode proporciona un nico nmero a cada carcter
independientemente de la plataforma, del programa o del lenguaje.
A continuacin se describe el conjunto mnimo de codicaciones que debe
soportar toda mquina virtual
J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

45/95

Entrada orientada a caracteres

US-ASCII

Cdigo de 7 bits.
ISO-8859-X

Diseado a mediados de los 80 con el n de codicar caracteres en otros


lenguajes. ISO-8859-1 (Latin-1), ISO-8859-2 (Latin-2),...
UTF-16

UTF-16 utiliza un cdigo de 16 bits para representar los caracteres. Existen


tres versiones: UTF-16, UTF-16BE y UTF-16LE.
UTF-16BE utiliza una representacin big-endian (el byte ms signicativo
primero), UTF-16LE utiliza una representacin little-endian (el byte
menos signicativo primero) y UTF-16 usa big-endian por defecto pero
puede incluir una marca para indicar cual es la representacin usada.

J. Gutirrez, Tema 3

Curso 12/13

46/95

Entrada/Salida

Entrada orientada a caracteres

UTF-8

UTF-8 codica con un nmero variable de bytes (desde un byte hasta


cuatro bytes). Esta codicacin es eciente si codica documentos que
utilizan caracteres US-ASCII ya que stos se codican con un nico byte.
UTF-8 es la codicacin por defecto para XML.
Algunas mquinas virtuales ofrecen soporte para otros conjuntos de
caracteres.
Por ejemplo en Windows se ofrece soporte para CP1252 que es una
modicacin del ASCII.

J. Gutirrez, Tema 3

Curso 12/13

Entrada/Salida

47/95

Entrada orientada a caracteres

La siguiente ilustracin muestra los bytes (en hexadecimal) de un chero


con dos caracteres para diferentes formatos.

a
UTF-16LE

FFFE

AF61

6100

a
UTF-16BE

FEFF

61AF

0061

a
UTF-8

EFBBBF

J. Gutirrez, Tema 3

E686AF

Curso 12/13

61

48/95

Entrada/Salida

Entrada orientada a caracteres

La clase de la que heredan las clases de entrada que trabajan con


caracteres es la clase Reader que est denida como abstracta.
Una clase que la extienda debe implementar los mtodos declarados
como abstractos read(char[], int, int) y close() .
Tiene el mtodo (entre otros)
public int read()throws IOException

para leer un nico carcter devuelto como un entero en el rango 0 a


65535 (0x0 - 0xFFFF) o -1 si se ha llegado al nal del chero.
Este mtodo bloquea la ejecucin hasta que el siguiente carcter est
disponible, se lance una excepcin o se alcance el nal del chero.

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

49/95

Entrada orientada a caracteres

Las clases que extienden a Reader para la lectura de caracteres de bajo


nivel en el paquete java.io son:
CharArrayReader
FileReader

Lee caracteres de un array de caracteres.

Lee caracteres de un chero.

StringReader

Lee caracteres de un String .

Establece un puente entre ujos orientados a bytes y


ujos orientados a caracteres.
InputStreamReader

J. Gutirrez, Tema 3

Curso 12/13

50/95

Entrada/Salida

Entrada orientada a caracteres

La siguiente gura muestra la jerarqua de las clases anteriores.

abstract

Reader

StringReader

InputStreamReader

CharArrayReader

FileReader

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

51/95

Entrada orientada a caracteres

Ejemplo: uso de un ujo de bajo nivel orientado a caracteres

En este ejemplo se lee un chero de caracteres asumiendo la codicacin


de caracteres por defecto.
import java . io .*;
class DemoFileReader {
public static void main ( String [] args ) {
int c;
try {
FileReader fr = new FileReader ( args [0]) ;
while (( c= fr . read () ) != -1)
System . out . print (( char )c);
fr . close () ;
} catch ( IOException e){
System . out . println ( " Error E/S ");
e. printStackTrace () ;
}
}

Si se ejecuta en Windows utilizar la codicacin por defecto que es la Cp1252. Si


el chero usa una codicacin Unicode entonces los caracteres no se mostrarn
correctamente.
J. Gutirrez, Tema 3

Curso 12/13

52/95

Entrada/Salida

Entrada orientada a caracteres

Ejemplo: uso de un ujo de bajo nivel orientado a caracteres

En este ejemplo se lee un chero de caracteres especicando la codicacin.


import java . io .*;
class DemoInputStreamReaderCodificacion {
public static void main ( String [] args ) {
int c;
try {
InputStreamReader fr = new InputStreamReader ( new
FileInputStream ( args [0]) ," UTF -8 ");

while (( c= fr . read () ) != -1)


System . out . print (( char )c);
fr . close () ;
} catch ( IOException e){
System . out . println ( " Error E/S ");
e. printStackTrace () ;
}

Nota: este programa solo mostrar los caracteres que coincidan con ASCII ya que
la consola no soporta Unicode.
J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

53/95

Entrada orientada a caracteres

Las clases que se ofrecen para entrada ltrada son:


Flujo de lectura que almacena los caracteres en un buer
para que la lectura sea eciente.

BufferedReader

PuschBackReader

Permite volver a poner en el ujo caracteres ledos.

Lee caracteres de un chero utilizando buer y


permitiendo consultar el nmero de lneas ledas.
LineNumberReader

J. Gutirrez, Tema 3

Curso 12/13

54/95

Entrada/Salida

Entrada orientada a caracteres

La jerarqua que siguen estas clases es:

abstract

Reader

abstract

BufferedReader

FilterReader

LineNumberReader

PushBackReader

J. Gutirrez, Tema 3

Curso 12/13

Entrada/Salida

55/95

Salida orientada a caracteres

ndice

3 Entrada/Salida

Entrada orientada a bytes


Salida orientada a bytes
Entrada orientada a caracteres
Salida orientada a caracteres
La clase Scanner

J. Gutirrez, Tema 3

Curso 12/13

56/95

Entrada/Salida

Salida orientada a caracteres

La clase de la que heredan las clases de salida que trabajan con


caracteres es la clase Writer que est denida como abstracta.
Una clase que la extienda debe implementar los mtodos
write(char[], int, int) , flush() y close() Adems puede
ocultar (o sobreescribir) alguno de los dems mtodos para
proporcionar mayor eciencia, funcionalidad adicional o ambos.
Tiene el mtodo (entre otros)
public write(int)throws IOException

para escribir un nico carcter.


El caracter a escribir est contenido en los 16 bits de bajo orden del
valor entero proporcionado, los 16 bits de ms alto orden son
desechados.

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

57/95

Salida orientada a caracteres

Las clases que extienden a Writer para la escritura de caracteres de bajo


nivel en el paquete java.io son:
CharArrayWriter
FileWriter

Escribe en un array de caracteres.

Escribe en un chero.

StringWriter

Escribe caracteres en un String.

Establece un puente entre ujos orientados a


caracteres y ujos orientados a bytes
OutputStreamWriter

J. Gutirrez, Tema 3

Curso 12/13

58/95

Entrada/Salida

Salida orientada a caracteres

La jerarqua que siguen estas clases es

abstract

Writer

StringWriter

OutputStreamWriter

CharArrayWriter

FileWriter

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

59/95

Salida orientada a caracteres

Las clases que se ofrecen para salida ltrada son:


Flujo de salida que almacena los caracteres en un buer
para que la escritura sea eciente.
BufferedWriter

Permite escribir tipos primitivos y objetos a un ujo de salida


orientado a caracteres.
PrintWriter

J. Gutirrez, Tema 3

Curso 12/13

60/95

Entrada/Salida

Salida orientada a caracteres

La jerarqua que siguen estas clases es:

abstract

Writer

BufferedWriter

PrintWriter

FilterWriter

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

61/95

Salida orientada a caracteres

Ejemplo: uso de ujo de salida ltrado orientado a caracteres I


import java . io .*;
import java . util .*;
class Punto {
private int x;
private int y;
Punto ( int cx , int cy )
x = cx ;
y = cy ;
}
public String toString () {
return "( " + x + " , " + y + ")" ;
}
}
class DemoPrintWriter {
public static void main ( String [] args ) {
try {
int i =20;
LinkedList lista = new LinkedList () ;
lista . add ( new Punto (0 ,0) );
lista . add ( new Punto (1 ,1) );
lista . add ( new Punto (2 ,2) );
PrintWriter pw = new PrintWriter (
new BufferedOutputStream ( new FileOutputStream (" fich . txt ")) , true ) ;
pw . println ( lista );
pw . println ( i);
pw . close () ;

J. Gutirrez, Tema 3

Curso 12/13

62/95

Entrada/Salida

Salida orientada a caracteres

Ejemplo: uso de ujo de salida ltrado orientado a caracteres II

} catch ( IOException e) {}

Ejecutando el programa anterior se crea el chero fich.txt cuyo


contenido es:
[(0 , 0) , (1 , 1) , (2 , 2) ]
20

La informacin sobre los puntos se obtiene del mtodo toString() de la


clase Punto .

J. Gutirrez, Tema 3

Entrada/Salida

J. Gutirrez, Tema 3

Curso 12/13

63/95

Salida orientada a caracteres

Curso 12/13

64/95

Entrada/Salida

La clase Scanner

ndice

3 Entrada/Salida

Entrada orientada a bytes


Salida orientada a bytes
Entrada orientada a caracteres
Salida orientada a caracteres
La clase Scanner

J. Gutirrez, Tema 3

Curso 12/13

Entrada/Salida

65/95

La clase Scanner

Clase Scanner

Esta clase permite realizar la conversin a tipos primitivos o cadenas de


una fuente (un ujo, una cadena, etc).
El Scanner trocea en partes lo que va leyendo usando un delimitador (que
por defecto es el espacio). Los trozos se convierte a valores de diferente
tipo mediante los diferentes mtodos next.
Por ejemplo este cdigo permite leer un entero de la entrada estndar
System.in

Scanner sc = new Scanner ( System . in ) ;


int i = sc . nextInt () ;

Este otro ejemplo permite leer valores long de un chero:


Scanner sc = new Scanner ( new File (" numeros . txt ") );
while ( sc . hasNextLong () ) {
long dato = sc . nextLong () ;
// Procesa el dato
}

J. Gutirrez, Tema 3

Curso 12/13

66/95

Entrada/Salida

La clase Scanner

Algunos constructores de la clase Scanner

Scanner ( File source )


// Constructs a new Scanner that produces values

scanned from the specified file .

Scanner ( File source , String charsetName )


// Constructs a new Scanner that produces values scanned from the specified file .
Scanner ( InputStream source )
// Constructs a new Scanner that produces values scanned from the specified input stream
.
Scanner ( InputStream source , String charsetName )
// Constructs a new Scanner that produces values scanned from the specified input stream
.
Scanner ( String source )
// Constructs a new Scanner that produces values scanned from the specified string .

J. Gutirrez, Tema 3

Entrada/Salida

Curso 12/13

67/95

La clase Scanner

Algunos mtodos de la clase Scanner

Mtodos para obtener valores:


boolean nextBoolean ()
// Scans the next token of the input into a boolean value and returns that value .
byte nextByte ()
// Scans the next token of the input as a byte .
double nextDouble ()
// Scans the next token of the input as a double .
float nextFloat ()
// Scans the next token of the input as a float .
int nextInt ()
// Scans the next token of the input as an int .
int nextInt ( int radix )
// Scans the next token of the input as an int .
String nextLine ()
// Advances this scanner past the current line and returns the input that was skipped .
long nextLong ()
// Scans the next token of the input as a long .
short nextShort ()
// Scans the next token of the input as a short .

J. Gutirrez, Tema 3

Curso 12/13

68/95

Entrada/Salida

La clase Scanner

Algunos mtodos de la clase Scanner

Mtodos para comprobar si hay disponible un valor de un tipo determinado


boolean hasNextBoolean ()
// true si el siguiente token se puede interpretar como un booleano
// Igual para el resto de valores

Mtodo para cambiar el delimitador:


Scanner useDelimiter ( String pattern )
// Sets this scanner 's delimiting pattern to a pattern constructed from the specified
String .

J. Gutirrez, Tema 3

Curso 12/13

69/95

Curso 12/13

70/95

Serializacin

ndice

Objetivos

Introduccin

Entrada/Salida

Serializacin

Material adicional

J. Gutirrez, Tema 3

Serializacin

Introduccin

ndice

4 Serializacin

Introduccin
Flujos para lectura y escritura de objetos
Implementando Serializable
Implementando Externalizable

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

71/95

Introduccin

La serializacin de objetos permite convertir cualquier objeto que


implemente a la interfaz Serializable o la interfaz
Externalizable en una secuencia de bits que puede ser utilizada
posteriormente para reconstruir el objeto original.
Esta secuencia de bits puede guardarse en un chero o puede enviarse
a otra mquina virtual (que puede estar ejecutndose en otro sistema
operativo) para reconstruir el objeto en otro instante o en otra
mquina virtual.
La posibilidad de guardar un objeto de forma que pueda existir incluso
cuando la aplicacin haya nalizado se conoce como persistencia.

J. Gutirrez, Tema 3

Curso 12/13

72/95

Serializacin

Introduccin

Los objetos mantienen referencias a otros objetos. Estos otros objetos


deben ser tambin almacenados y recuperados con el n de mantener
las relaciones originales. Por supuesto, todos estos objetos deben ser
serializables ya que de lo contrario se lanzar una excepcin del tipo
NotSerializableException .
Para reconstruir un objeto (o conjunto de objetos) que ha sido
serializado es necesario que la clase (o clases) (archivo .class) est en
el classpath con el n de indenticarla y vericarla antes de
restaurar el contenido en una nueva instancia.
La serializacin se introdujo en Java para soportar la Invocacin
Remota de Mtodos (RMI) que permite a una aplicacin enviar
mensajes a un objeto remoto (que se est ejecutando en otra mquina
virtual).

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

73/95

Flujos para lectura y escritura de objetos

ndice

4 Serializacin

Introduccin
Flujos para lectura y escritura de objetos
Implementando Serializable
Implementando Externalizable

J. Gutirrez, Tema 3

Curso 12/13

74/95

Serializacin

Flujos para lectura y escritura de objetos

Java proporciona clases para crear ujos de entrada (


ObjectInputStream ) y de salida ( ObjectOutputStream ) de objetos.
Pasos para realizar la serializacin:
1
2

Se crea un objeto del tipo OutputStream


Este objeto se pasa como argumento al constructor de
ObjectOutputStream

Esta clase tiene (entre otros) el mtodo writeObject(Object obj)


que serializa el objeto.

Pasos para realizar la recuperacin:


1
2

Se crea un objeto del tipo InputStream


Este objeto se pasa como argumento al constructor de
ObjectInputStream

Esta clase tiene (entre otros) el mtodo Object readObject() que


permite recuperar el objeto.
J. Gutirrez, Tema 3

Curso 12/13

Serializacin

75/95

Flujos para lectura y escritura de objetos

La jerarqua que siguen las clases para la serializacin de objetos es:

interface

abstract

DataOutput

OutputStream

interface

interface

ObjectOutput

ObjecStreamConstants

ObjectOutputStream

J. Gutirrez, Tema 3

Curso 12/13

76/95

Serializacin

Flujos para lectura y escritura de objetos

La jerarqua que sigue la clase para la recuperacin de objetos serializados


es:

interface

abstract

DataInput

InputStream

interface

interface

ObjectInput

ObjecStreamConstants

ObjectInputStream

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

77/95

Implementando Serializable

ndice

4 Serializacin

Introduccin
Flujos para lectura y escritura de objetos
Implementando Serializable
Implementando Externalizable

J. Gutirrez, Tema 3

Curso 12/13

78/95

Serializacin

Implementando Serializable

Lo ms simple

Una clase se convierte en serializable implementando la interface


java.io.Serializable .
Cualquier subclase de una clase que implemente a esta interface se
convierte automticamente en serializable.
Esta interface no dene ningn mtodo ni ningn atributo y sirve
nicamente para indicar que la clase es serializable.
Al recorrer el grafo de referencias, se puede encontrar que un objeto
no implementa la interface Serializable . En este caso se lanza una
excepcin del tipo NotSerializableException .
Los atributos declarados como transient no se seralizan.

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

79/95

Implementando Serializable

Durante el proceso de serializacin se asocia a cada clase un nmero


de versin llamado serialVersionUID , que se utiliza durante la
recuperacin para vericar que la versin serializada del objeto es
compatible con la clase cargada.
Si la clase cargada tiene un serialVersionUID diferente del
serialVersionUID correspondiente a la clase cuya instancia se
serializ entonces se produce una excepcin InvalidClassException
.
Una clase serializable puede declarar su propio serialVersionUID
explcitamente declarando un atributo llamado serialVersionUID
static final long serialVersionUID

Si no se especica ninguno, entonces se calcular uno para la clase.


Sin embargo es recomendable que las clases serializables declaren
explcitamente este atributo.

J. Gutirrez, Tema 3

Curso 12/13

80/95

Serializacin

Implementando Serializable

Ejemplo Serializable I

En este ejemplo hay 3 clases, una clase Punto y ListaPuntos que


implementan a Serializable y otra clase DemoSerializacion que
contiene el main .
En el main se crea un objeto del tipo ListaPuntos (que contiene
objetos de tipo Punto ) y se serializa a un chero. A continuacin se
recupera el objeto del chero y se le envan mensajes para comprobar que
se ha reconstruido correctamente.
import java . io .*;
import java . util .*;
/* * Clase que representa un punto 2d */
class Punto implements Serializable {
private int x;
private int y;
Punto ( int cx , int cy ){
System . out . println ( " Creando el punto (" + cx + " , " + cy + ") ");
x = cx ;
y = cy ;

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

81/95

Implementando Serializable

Ejemplo Serializable II
}
public int getX () {
return x;
}

public int getY () {


return y;
}

class ListaPuntos implements Serializable {


private LinkedList lista = new LinkedList () ;
ListaPuntos ( int nPuntos ){
System . out . println ( " Constructor de ListaPuntos ");
int x ,y ;

for ( int i =0; i < nPuntos ; i ++) {


x = ( int ) ( Math . random () *10) ;
y = ( int ) ( Math . random () *10) ;
lista . add ( new Punto (x ,y ));
}

public void muestraPuntos () {


ListIterator li = lista . listIterator (0) ;
Punto p ;

J. Gutirrez, Tema 3

Curso 12/13

82/95

Serializacin

Implementando Serializable

Ejemplo Serializable III

while ( li . hasNext () ) {
p =( Punto ) li . next () ;
System . out . println ( "x = " + p. getX () + " , y = " + p. getY () );
}

public class DemoSerializacion {


public static void main ( String [] args ) {
ListaPuntos s = new ListaPuntos (5) ;
try {
ObjectOutputStream salida = new ObjectOutputStream (
new FileOutputStream ( " objeto . bin ") );
salida . writeObject ( s);
salida . close () ;
System . out . println ( " Recuperando el objeto ... " );
ObjectInputStream entrada = new ObjectInputStream (
new FileInputStream (" objeto . bin ")) ;
ListaPuntos lp = ( ListaPuntos ) entrada . readObject () ;
entrada . close () ;
lp . muestraPuntos () ;

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

83/95

Implementando Serializable

Ejemplo Serializable IV

} catch ( FileNotFoundException fnfe ){ System . out . println (" Error E/S" );


} catch ( IOException ioe ){ System . out . println (" Error E /S" );
} catch ( ClassNotFoundException ioe ){ System . out . println (" Clase no encontrada " );
}

J. Gutirrez, Tema 3

Curso 12/13

84/95

Serializacin

Implementando Serializable

La ejecucin del programa anterior produce el siguiente resultado:


Constructor de ListaPuntos
Creando el punto (7 , 4)
Creando el punto (8 , 7)
Creando el punto (3 , 2)
Creando el punto (0 , 3)
Creando el punto (6 , 4)
Recuperando el objeto ...
x = 7, y = 4
x = 8, y = 7
x = 3, y = 2
x = 0, y = 3
x = 6, y = 4
Press any key to continue ...

Como puede observarse, durante la reconstruccin de los objetos no se


llama a ninguno de los constructores sta se realiza nicamente a partir de
los bytes almacenados.

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

85/95

Implementando Serializable

Modicacin del comportamiento bsico

Las clases que requieran algn tratamiento especial durante los procesos de
serializacin y reconstruccin deben implementar mtodos especiales:
private void writeObject(ObjectOutputStream out)throws IOException
private void readObject(ObjectInputStream in)throws IOException,
ClassNotFoundException

El mtodo writeObject es el responsable de escribir los atributos del


objeto.
El mtodo readObject es el responsable de leer del ujo y restaurar los
atributos.

J. Gutirrez, Tema 3

Curso 12/13

86/95

Serializacin

Implementando Externalizable

ndice

4 Serializacin

Introduccin
Flujos para lectura y escritura de objetos
Implementando Serializable
Implementando Externalizable

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

87/95

Implementando Externalizable

Otra opcin a la hora de controlar qu es lo que se serializa de un


objeto es implementar la interfaz Externalizable en lugar de la
interfaz Serializable .
La interfaz Externalizable extiende a Serializable aadiendo
dos mtodos, writeExternal() y readExternal() que son
llamados automticamente durante la serializacin y la recuperacin.
Si un objeto implementa a Externalizable no se serializa
automticamente nada y se debe especicar lo que se debe serializar
mediante llamadas a writeExternal() .

J. Gutirrez, Tema 3

Curso 12/13

88/95

Serializacin

Implementando Externalizable

import java . io .*;


import java . util .*;
class Usuario implements Externalizable {
private String usuario ;
private String password ;
public Usuario () {
System . out . println ( " Creando usuario vacio " );
}
Usuario ( String u , String p){
System . out . println ( " Creando Usuario (" + u + " , " + p + " )");
usuario = u ;
password = p;
}
public void writeExternal ( ObjectOutput out )
throws IOException {
System . out . println ( " Usuario . writeExternal " );
// Explicitamente indicamos cuales son los atributos a almacenar
out . writeObject ( usuario ) ;
}
public void readExternal ( ObjectInput in )
throws IOException , ClassNotFoundException {
System . out . println ( " Usuario . readExternal ");
// Explicitamente indicamos cuales son los atributos a recuperar

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

89/95

Implementando Externalizable

usuario = ( String ) in . readObject () ;

public void muestraUsuario () {


String cad =" Usuario : " + usuario + "
if ( password == null )
cad = cad + " No disponible " ;
else
cad = cad + password ;
System . out . println ( cad );
}

Password : ";

class ListaUsuarios implements Serializable {


private LinkedList lista = new LinkedList () ;
int valor ;
ListaUsuarios ( String [] usuarios , String [] passwords ){

for ( int i =0; i < usuarios . length ; i ++)


lista . add ( new Usuario ( usuarios [i], passwords [ i ]) );

public void muestraUsuarios () {


ListIterator li = lista . listIterator (0) ;
Usuario u;
while ( li . hasNext () ) {
u =( Usuario ) li . next () ;

J. Gutirrez, Tema 3

Curso 12/13

90/95

Serializacin

Implementando Externalizable

u. muestraUsuario () ;

class DemoExternalizable {
public static void main ( String [] args )
throws IOException , ClassNotFoundException {
System . out . println ( " Creando el objeto ") ;
String [] usuarios ={ "A" ,"B" ,"C " };
String [] passwords ={ "1 " ," 2" ," 3" };
ListaUsuarios lp = new ListaUsuarios ( usuarios , passwords );
System . out . println ( "\ nAlmacenando objeto ") ;
ObjectOutputStream o =
new ObjectOutputStream (
new FileOutputStream ( " objetos . out " ));
o. writeObject ( lp );
o. close () ;
System . out . println ( "\ nRecuperando objeto ") ;
ObjectInputStream in =
new ObjectInputStream (
new FileInputStream (" objetos . out ") );
lp = ( ListaUsuarios ) in . readObject () ;

J. Gutirrez, Tema 3

Curso 12/13

Serializacin

91/95

Implementando Externalizable

lp . muestraUsuarios () ;

J. Gutirrez, Tema 3

Curso 12/13

92/95

Serializacin

Implementando Externalizable

La ejecucin del programa anterior produce el siguiente resultado:


Creando
Creando
Creando
Creando

el objeto
Usuario (A , 1)
Usuario (B , 2)
Usuario (C , 3)

Almacenando objeto
Usuario . writeExternal
Usuario . writeExternal
Usuario . writeExternal
Recuperando objeto
Creando usuario vacio
Usuario . readExternal
Creando usuario vacio
Usuario . readExternal
Creando usuario vacio
Usuario . readExternal
Usuario : A
Password : No disponible
Usuario : B
Password : No disponible
Usuario : C
Password : No disponible
Press any key to continue ...

Como puede observarse, (al contrario que en la serializacin) al recuperar


un objeto que ha sido externalizado se llama al constructor por defecto as
que este debe ser accesible.
J. Gutirrez, Tema 3

Curso 12/13

93/95

Curso 12/13

94/95

Material adicional

ndice

Objetivos

Introduccin

Entrada/Salida

Serializacin

Material adicional

J. Gutirrez, Tema 3

Material adicional

Para saber ms...

Java 2, Fundamentos, Cay S. Horstmann / Gary Cornell. 2003


Prentice Hall.
Captulo 12 (Flujos y cheros).
Java I/O, Elliotte Rusty Harold. 1999 O'Reilly.
Tutorial dedicado a entrada/salida: http://docs.oracle.com/
javase/tutorial/essential/io/index.html

J. Gutirrez, Tema 3

Curso 12/13

95/95

Вам также может понравиться