Está en la página 1de 176

Core Java

Cdigo del Curso: CY420


Versin: 5.1

Gua del Estudiante

Libro 2: Core Java

IBM Training
Worldwide Certified Material

Informacin Sobre la Publicacin


Esta publicacin ha sido producida usando Microsoft Word 2000 y Microsoft PowerPoint
2000 para Windows.
Marcas Registradas
IBM es una marca registrada por International Business Machines Corporation.
Otras compaas, productos, y nombre de servicios pueden ser marcas registradas o
marcas de servicios de otros.
Marcas Registradas de otras Compaas
HotJava browser, Java Development Kit (JDK), Java, Java Servlet, Solaris, Enterprise
Java Beans, Java Server Pages, JDK, JSP Sun Microsystems, Microsoft MAKECAB,
Windows operating system, ASP, VB, .NET, VC++, Microsoft Access, Microsoft SQL
Server, Microsoft ODBC for Oracle Microsoft Corp, WinZip Nico Mak Computing,
Inc., Time Time Warner, JDBC Javasoft, Oracle Oracle Corporation, Sybase
Sybase Inc., UDB DB2 IBM.
Edicin Octubre 2007
La informacin contenida en este documento no ha sido sometida a ninguna prueba
formal de IBM y es distribuida bsicamente como es" sin ninguna garanta ya sea
expresa o implcita. El uso de esta informacin o la implementacin de cualquiera de
estas tcnicas es responsabilidad del comprador y depender de la habilidad de ste
para su evaluacin e integracin en el ambiente operacional del comprador. A pesar de
que cada tema ha sido revisado por IBM para su exactitud en una situacin especfica,
no hay garanta de que obtener el mismo resultado o uno similar a ste en otra
situacin. Los compradores que intenten adaptar estas tcnicas a sus propios
ambientes lo hacen bajo su propio riesgo.
Copyright International Business Machines Corporation, 2007. All rights reserved.
Este documento no puede ser reproducido en su totalidad o en parte sin el previo
permiso escrito de IBM.
Instrucciones Especiales para la Impresin de este Curso:
No elimine pginas en blanco que puedan aparecer al final de cada unidad o entre
unidades. Estas pginas fueron insertadas intencionalmente.

Gua del Estudiante

Core Java

Contenido
Volumen 3: Manejo de Excepciones .................................................................1
Unidad 1: Manejo de Excepciones y Tipos de Excepciones...........................3
Objetivos de Aprendizaje

1. Introduccin

2. Tcnicas Tradicionales de Manejo de Errores

3. Excepciones y Condiciones Anormales

4. Java y el Manejo de Excepciones

5. Agrupar Excepciones en Java

14

6. Excepciones Verificadas y No Verificadas

17

7. La Clase Throwable y sus Clases Derivadas

17

8. Manejo de Excepciones

19

9. Flujo de Manejo de Excepciones

21

Resumen

23

Unidad 1: Examen de Autoevaluacin

24

Respuestas a la Unidad 1: Examen de Autoevaluacin

27

Unidad 2: Lanzamiento y Manejo de Excepciones ........................................29


Objetivos de Aprendizaje

29

1. Introduccin

30

2. Excepciones Estndar en Java

30

3. Usar la Jerarqua de Excepciones

32

4. La Clusula finally Revisada

34

5. Sobrescribir Mtodos que Lanzan Excepciones

36

6. Crear Excepciones Definidas por el Usuario

39

7. Ms de Excepciones Definidas por el Usuario

42

8. La Clusula throws Revisada

45

Resumen

50

Unidad 2: Examen de Autoevaluacin

51

Respuestas a la Unidad 2: Examen de Autoevaluacin

53

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones ..............55


Objetivos de Aprendizaje

55

Ejercicios de Laboratorio

56

Volumen 4: Facilidades de Entrada / Salida ...................................................56


Unidad 1: Archivos y Flujos.............................................................................56
i
Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Objetivos de Aprendizaje

56

1. Introduccin

56

2. Archivos

56

3. Flujos

56

4. La Clase InputStream

56

5. La Clase OutputStream

56

6. La Clase Reader

56

7. La Clase Writer

56

8. La Clase Scanner

56

Resumen

56

Unidad 1: Examen de Autoevaluacin

56

Respuestas a la Unidad 1: Examen de Autoevaluacin

56

Unidad 2: Laboratorio de Archivos y Flujos...................................................56


Objetivos del Aprendizaje

56

Ejercicios de Laboratorio

56

Unidad 3: Serializacin de Objetos .................................................................56


Objetivos del Aprendizaje

56

1. Introduccin

56

2. Serializacin de Objetos

56

3. Aplicaciones de la Serializacin de Objetos

56

4. Implementando Serializacin en Java

56

Resumen

56

Unidad 3: Examen de Autoevaluacin

56

Respuestas a la Unidad 3: Examen de Autoevaluacin

56

Unidad 4: Laboratorio de Serializacin de Objetos .......................................56


Objetivos del Aprendizaje

56

Ejercicios de Laboratorio

56

ii
Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Volumen 3: Manejo de Excepciones

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 1


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 1: Manejo de Excepciones y


Tipos de Excepciones
Objetivos de Aprendizaje
Al final de esta unidad, usted ser capaz de:

Definir las excepciones y explicar las tcnicas tradicionales de manejo de


errores.

Describir el manejo de excepciones en Java.

Diferenciar entre excepciones verificadas y no verificadas.

Describir las sub-clases de la clase Throwable.

Describir el flujo de manejo de excepciones en Java.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 3


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

1. Introduccin
En el Volumen 2 Programacin Orientada a Objetos, se revis Java como lenguaje de
programacin y se identificaron los conceptos de clases, objetos, modificadores de
acceso, herencia en java, interfaces y paquetes. En esta unidad, se discutir como se
manejan los errores en un programa.
Los programas no estn siempre libres de errores, en Java cuando ocurre una
condicin de error, se lanza una excepcin. Las excepciones son eventos anormales
que ocurren durante el curso de la ejecucin de un programa y rompen la secuencia
normal de ejecucin del programa.
Algunas de las preguntas inherentes a las excepciones, que le pueden surgir al
programador son las siguientes:

Necesariamente un programa debe manejar eventos anormales?

El cdigo para el manejo de errores debe asociarse con cul parte del
programa?

Cmo se detecta y maneja el error durante el tiempo de ejecucin?

Qu le pasa a la aplicacin cuando se maneja un error?

Proveen los lenguajes de programacin soporte para encontrar y manejar


errores?

Muchas de estas preguntas sern respondidas en esta y la prxima unidad. Para


empezar se discuten las tcnicas tradicionales para el manejo de errores.

2. Tcnicas Tradicionales de Manejo de Errores


En los inicios de la programacin de computadoras, lenguajes como Pascal, Fortran y C
no provean ningn soporte a los programadores para el manejo de errores. Era
responsabilidad del programador proveer rutinas para el manejo de errores, debido a
esto, muchos errores importantes no eran detectados en las aplicaciones. Todo esto se
dedujo, porque el cdigo para el manejo del error estaba escrito junto con el programa
principal, esto haca difcil distinguir el flujo del programa principal del cdigo para
manejo de errores. Adicionalmente, esta situacin complicaba el proceso de depuracin
del programa.
Lenguajes de programacin desarrollados posteriormente como BASIC y COBOL
provean un soporte estructurado para la revisin y manejo de errores. Proporcionaban
la siguiente construccin del lenguaje para el manejo de errores:
ON ERROR GOTO ...
Esta construccin separaba el cdigo para el manejo del error del cdigo principal.
Cuando un programa encontraba un error, el control del programa saltaba a la posicin
especificada por el GOTO. La posicin especificada contena el cdigo para el manejo
Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 4

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

del error. Lenguajes de programacin diferentes provean sintaxis diferentes para la


deteccin y manejo de errores. Sin embargo, la estructura bsica era similar a la
mencionada anteriormente.
Aunque el cdigo para manejo de errores con un lenguaje que lo soportara era mejor
que ningn soporte, el cdigo del programa principal todava se intercalaba con el
cdigo para la verificacin y manejo de errores. Adems, el flujo de ejecucin era
interrumpido ya que el control saltaba a una posicin diferente para luego retornar
despus de manejado el error. Con la evolucin de la programacin orientada a objetos,
se introdujo una nueva forma de manejar los errores, en la cual, el cdigo para el
manejo del error era separado del cdigo del programa principal.

3. Excepciones y Condiciones Anormales


Como se mencion anteriormente, las excepciones son eventos anormales que ocurren
durante la ejecucin del programa. Los siguientes son algunos ejemplos de cuando se
lanzan excepciones:

Cuando un nmero es dividido entre cero. Esto puede ser detectado slo en
tiempo de ejecucin, ya que las operaciones se efectan durante la ejecucin
del programa.

Cuando se accede a un elemento de un arreglo que esta fuera del lmite del
arreglo.

Cuando ocurre una condicin de desborde (overflow o underflow) durante la


asignacin de valores a variables numricas.

Cuando un recurso que es requerido por la aplicacin no est disponible. Una


aplicacin, por ejemplo, puede requerir una impresora y la impresora puede no
estar conectada a la computadora.

Cuando un programa requiere un archivo para lectura, y el archivo no est


disponible en el sistema de archivos.

Cuando un programa accede a recursos del sistema sin autorizacin.

Estos son solo algunos ejemplos de cuando puede ocurrir una excepcin en un
programa. Algunas de estas no son lo suficientemente serias y la ejecucin del
programa puede continuar, una vez manejadas, pero hay excepciones que no permiten
que contine la ejecucin del programa.
A continuacin se discute el soporte provisto por Java para el manejo de excepciones.

4. Java y el Manejo de Excepciones


Java tiene incorporado la capacidad para asegurar que las excepciones son manejadas
dentro del programa. Aunque los programadores pueden manejar algunos errores, otros
son manejados por la JVM. El programador debe manejar un error como el de archivo
no encontrado, mientras que el error fuera de memoria ser manejado por la JVM. La

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 5


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Figura 1.1 muestra la secuencia de acciones que ocurren cuando se presenta una
condicin anormal.

Figura 1.1: Secuencia de Acciones Cuando se Produce una Excepcin

Se discute a continuacin lo que significa arrojar una excepcin.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 6

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

En Java, cuando ocurre un error, ste se encuentra en un mtodo. El mtodo crea un


objeto de la excepcin que ocurri, para manejar el error, y separar el manejo del error
del cdigo actual. As, si el mtodo estaba efectuando algn clculo matemtico, si la
variable no puede tomar un valor negativo, un objeto de la excepcin que puede
manejar esta excepcin ser creado. En Java, todas las clases excepcin son derivadas
de la clase base Exception.
Una vez creado el objeto excepcin, el mtodo pasa el objeto excepcin al sistema de
tiempo de ejecucin Java, este pase del objeto se hace a travs del concepto de lanzar
la excepcin. El sistema de tiempo de ejecucin busca en la pila de llamadas y ubica el
mtodo que manejar la excepcin levantada. La pila de llamadas tendr detalles de
cmo se llam al mtodo que origin la excepcin. En el caso de que el mtodo ms
interno lance un error y no lo maneje, la excepcin ser pasada en forma ascendente
por la pila de llamadas hasta que se consiga un mtodo que maneje la excepcin. Si se
consigue este mtodo, la excepcin es manejada, sino la ejecucin del programa se
detiene.
Java brinda soporte al manejo de excepciones con el uso de cinco palabras claves, que
son: try, catch, throw, throws y finally. Se explican cada una de ellas en las
siguientes secciones.

4.1 Usando Bloques try y catch


Java provee dos clusulas para el manejo de excepciones en una forma sofisticada. Se
pueden manejar las excepciones en un programa Java, usando las clusulas try y
catch. Se usarn los trminos bloques y clusulas indistintamente, cuando se haga
referencia a try, catch y finally (este ltimo tratado en una seccin posterior). A
continuacin se presenta un ejemplo para apreciar la importancia de separar la revisin
y manejo del error del cdigo principal.
Ejemplo 1.1
Asuma que se quiere obtener el n-simo elemento de una lista de elementos diferentes
si este es un string. El algoritmo es el siguiente:
El algoritmo comienza aqu
1. recuperarNEsimoElemento() {
2.
aceptar lista;
3.
obtener n-esimo elemento de la lista;
4.
5. }

retornar el elemento si es un String o retornar nulo;

El algoritmo termina aqu


El algoritmo anterior no incluye nada para la verificacin y manejo de errores. Se tienen
cuatro eventos de revisin de error que puede proveer la funcin anterior:
Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 7


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Si la lista es null.
Si la lista esta disponible, pero vaca.
Si el valor de 'N' no es un ndice vlido en la lista.
Si el elemento N no es un string.
Ahora se expande el algoritmo anterior para incluir el manejo de errores.
El algoritmo comienza aqu
1. String recuperarNEsimoElemento(List lista, int n) {
2.
3.
4.

String str;

5.
6.
7.

str = "Lista nula";


else if (esVacio(lista))
str = "Lista vacia";

8.
9.
10.

else if (n < 0 || n > numeroDeElementos(lista))


str = "Indice invalido";
else {

if (lista == null)

11.
12.
13.

str = getElemento(lista, n);


if (!esString(str))
str = "No es un String";

14.
15.
16.
17.

}
return str;
}

El algoritmo termina aqu


Se ha intercalado el cdigo principal con el cdigo para manejo de errores, hacindolo
difcil de entender. Se va a ver como manejar los errores anteriores en Java.
El cdigo Java comienza aqu
1. // Definicion de Metodo en Java
2. String recuperarNEsimoElemento(List lista, int n) {
3.
try {
4.
1) Obtener n-esimo elemento de la lista;
5.
6.

2) Retornar el elemento si es un String o retornar null;


} catch (lista_es_nula) {

7.
8.

1) Manejo de la excepcion cuando la lista es nula;


} catch (lista_esta_vacia) {

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 8

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

9.
10.
11.

1) Manejo de la excepcion cuando la lista esta vacia;


} catch (indice_invalido) {
1) Manejo de la excepcion cuando el indice es invalido;

12.
13.
14.

} catch (elemento_no_es_String) {
1) Manejo de la excepcion cuando el elemento a
recuperar no es un String;

15.
16. }

El cdigo Java termina aqu


En el cdigo anterior, se nota que el cdigo para manejo de errores est separado del
cdigo principal, que se concentra en la funcionalidad del mtodo. El cdigo que puede
generar una excepcin se coloca dentro del bloque try, y el cdigo para el manejo del
error se coloca dentro del bloque catch apropiado. Aunque, el algoritmo anterior es
muy elegante, se debe recordar que el programador tiene que escribir el cdigo para
manejar la excepcin.
Fin del Ejemplo 1.1
Se mostrar ahora el uso de la clusula throws en Java.

4.2 Usando la Clusula throws


La clusula throws se usa cuando un mtodo que lanza una excepcin no maneja la
excepcin. Asuma que el mtodo recuperarNEsimoElemento() no maneja ninguna
excepcin y que es invocado por el mtodo validarLista(), entonces
recuperarNEsimoElemento() debe especificar las excepciones que lanza, usando
la clusula throws, como a continuacin:
public String recuperarNEsimoElemento(List lista, int n)
throws Excepcion1, Excepcion2, Excepcion3, Excepcion4 {
// Obtiene el n-esimo elemento de la lista;
// Retorna elemento si es String o retorna null;
}
Un mtodo puede lanzar una o ms excepciones. Todava no se ha mostrado como se
lanzan las excepciones, se explica en la Seccin 4.3 La Sentencia throw. Debido a
que el mtodo recuperarNEsimoElemento() no maneja las excepciones, debe usar
la palabra reservada throws en su encabezado de mtodo. Todas las excepciones
verificadas lanzadas deben ser especificadas en el encabezado del mtodo, los
nombres usados en el ejemplo anterior son los nombres de las clases excepcin
creadas para manejar las diferentes excepciones. El mtodo validarLista() ser
como a continuacin se muestra:
public void validarLista(List lista, int n) {
Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 9


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

try {
recuperarNEsimoElemento(lista, n);
// Otras sentencias
} catch (lista_es_nula) {
// Manejo de la excepcion cuando la lista es nula;
} catch (lista_esta_vacia) {
// Manejo de la excepcion cuando la lista esta vacia;
} catch (indice_invalido) {
// Manejo de la excepcion cuando el indice es invalido;
} catch (elemento_no_es_String) {
// Manejo de la excepcion cuando el elemento a
// recuperar no es un String;
}
}
Se puede ver del cdigo anterior que el bloque try-catch se uso en el mtodo
validarLista() en lugar de en el mtodo recuperarNEsimoElemento(). Si
validarLista() no maneja la excepcin, necesita especificar usando la clusula
throws las excepciones que no maneja. Finalmente, las excepciones deben ser
manejadas en algn punto del programa, dentro de la pila de llamadas. Si ningn
manejador esta disponible la JVM maneja la excepcin, y finaliza.
Se explic como manejar excepciones usando los bloques try y catch, adems de
como el mtodo que lanza una excepcin, lo indica, usando la clusula throws. A
continuacin se explica como se puede lanzar una excepcin.

4.3 La Sentencia throw


La clusula throws se usa para indicar cual mtodo puede lanzar una excepcin.
Cuando ocurre un error en un programa, justo en el punto donde ocurre, una excepcin
es levantada, esto se hace usando la sentencia throw en Java.
Observe el algoritmo anterior para entender como usar la sentencia throw para lanzar
la excepcin.
El algoritmo comienza aqu
tipoDeRetorno nombreMetodo(tipoDeDato nombreArgumento)
throws NombreExcepcion {
// Declaraciones
// Algunas sentencias
if (algunaCondicion)
throw new NombreExcepcion();
Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 10

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

else {
// Continuar
}
}
El algoritmo termina aqu
En el algoritmo anterior, cuando algunaCondicion es verdadera, se lanza una
excepcin usando la sentencia throw. La sentencia throw lanza un objeto de la clase
excepcin NombreExcepcion. Este objeto debe pertenecer a la clase excepcin
especificada en la clusula throws. En el ejemplo anterior, la sentencia throw crea un
objeto de la clase NombreExcepcion y lo lanza. A menos que una excepcin sea
arrojada en el programa, no puede ser tomada o manejada en ningn lugar.
Un mtodo puede lanzar ms de una excepcin de la siguiente manera:
El algoritmo comienza aqu
tipoDeRetorno nombreMetodo(tipoDeDato nombreArgumento)
throws NombreExcepcion1,
NombreExcepcion2 {
// Declaraciones
// Algunas sentencias
if (algunaCondicion1)
throw new NombreExcepcion1();
else {
// Continuar
if (algunaCondicion2)
throw new NombreExcepcion2();
else
// Continuar
}
}
El algoritmo termina aqu
En el algoritmo anterior, el mtodo lanza dos excepciones mediante el uso de dos
sentencias throw en el cuerpo del mtodo. Si alguno de los mtodos en una clase
lanza un objeto excepcin que no concuerda con las clases excepcin especificadas en
la clusula throws del mtodo, se genera un error en tiempo de compilacin.
El mtodo recuperarNEsimoElemento() usado anteriormente se muestra ahora con
las sentencias throw incluidas:

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 11


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

El cdigo Java comienza aqu


public String recuperarNEsimoElemento(List lista, int n)
throws ListaNullExcepcion,
ListaVaciaExcepcion,
IndiceInvalidoExcepcion,
ElementoNoEsStringExcepcion {
String elemento = null;
if (lista == null)
throw new ListaNullExcepcion();
if (esVacio(lista))
throw new ListaVaciaExcepcion();
if (n < 0 || n > numeroDeElementos(lista))
throw new IndiceInvalidoExcepcion();
elemento = getElemento(lista, n);
if (!esString(elemento))
throw new ElementoNoEsStringExcepcion();
return elemento;
}
El cdigo Java termina aqu
En el cdigo anterior, se ve como el mtodo lanza cuatro excepciones explcitamente
usando la sentencia throw. Si el mtodo que invoca al mtodo anterior no maneja las
excepciones, entonces solamente debe especificar la clusula throws en su
declaracin de mtodo. Solo la clase que levanta la excepcin usa la sentencia throw.
A continuacin se explicar el uso de la clusula finally en los programas.

4.4 Usando el Bloque finally


Se vio que en el bloque try-catch, el bloque try contiene el cdigo que puede
generar la excepcin, y el bloque catch captura las excepciones indicadas lanzadas
por el bloque de cdigo y las maneja. Existe otro tipo de bloque, llamado bloque
finally, que puede ser aadido al final de todos los bloques catch. Se usa
bsicamente para tareas de limpieza, como cerrar archivos y liberar recursos.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 12

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

El bloque finally se ejecuta despus de la ejecucin de todos los bloques catch. El


bloque finally siempre se ejecuta an cuando no se lance ninguna excepcin en el
bloque try o aunque los bloques try-catch tengan una sentencia return. El
siguiente algoritmo muestra la estructura general del bloque try-catch-finally:
El algoritmo comienza aqu
try{
// Cdigo que puede generar las execpciones
}
catch (ChequeoExcepcion1 x1) {
// Cdigo para manejo de la excepcin
}
catch (ChequeoExcepcion2 x2) {
// Cdigo para manejo de la excepcin
}
finally(){
// Cdigo de limpieza
}
El algoritmo termina aqu
La Figura 1.2 explica el uso del bloque finally.

Figura 1.2: Uso del Bloque finally

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 13


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

La Figura 1.2 muestra dos escenarios en los cuales se invoca el cdigo en el bloque
finally. Se explica a continuacin cada uno de ellos.
En el primer escenario, el mtodo lanza todas las excepciones, ya que no hay un bloque
catch. El bloque finally es ejecutado siempre. Aqu, la organizacin esta
garantizada, al quedar separado el manejo de excepciones.
El segundo escenario muestra sentencias catch adems del bloque finally. El
mtodo captura las excepciones que coincidan con las del bloque catch. El bloque
catch lanza una nueva excepcin. La pulcritud esta todava garantizada.
Java tambin permite a los programadores crear sus propias excepciones. Esto les
ayuda a manejar situaciones de error que podran surgir de acuerdo al comportamiento
de los objetos de las clases escritas por ellos. Se discutir en detalle esta caracterstica
poderosa en la Unidad 2- Lanzamiento y Manejo de Excepciones.
A continuacin se explica como se pueden agrupar las excepciones.

5. Agrupar Excepciones en Java


Varias excepciones pueden ocurrir en un programa Java. Clasificar las excepciones las
hacen ms fciles de manejar.
Las excepciones que denotan desborde del tipo (overflow y underflow) en enteros y la
divisin de un nmero entre cero, pueden ser clasificadas en una categora. Las
excepciones relacionadas con la manipulacin de arreglos, como ndice fuera de lmites
o elemento no presente pueden ser agrupadas en otra categora. Las excepciones
relacionadas con las pilas como pila vaca o pila llena pueden ser agrupadas
separadamente, y tambin las excepciones que se ocupan de la lectura o escritura en
archivos pueden ser agrupadas aparte.
Es posible clasificar las excepciones, debido a que Java soporta la herencia. Se puede
tener una superclase que especifique las caractersticas comunes a todas las
excepciones de un tipo en particular. Todas las excepciones bajo una misma categora
pueden heredar de esta super clase.
Todos los tipos de excepciones y errores en Java son sub-clases de la clase
Throwable o una de las sub-clases de la clase Throwable.
La Figura 1.3 representa la agrupacin de las excepciones relacionadas con pilas.
En la representacin jerrquica de las clases excepcin, los nodos hoja denotan tipos
especficos de excepciones y errores, adems los nodos intermedios denotan una
categora general de la excepcin.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 14

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

En la Figura 1.3, PilaVaciaExcepcion y PilaLlenaExcepcion denotan dos tipos


especficos de excepciones de pila. La PilaExcepcion representa la categora
general de las excepciones de pila.

Figura 1.3: Jerarqua Hipottica de las Excepciones de Pila

La Figura 1.4 representa los errores que ocurren en la lectura y escritura de archivos.

Figura 1.4: Jerarqua Hipottica de la Excepciones de la Clase File

Nota: Las excepciones en las sub-clases deben ser manejadas antes que las
excepciones en las superclases. Si las superclases son manejadas primero, el cdigo
que maneja las subclases nunca alcanzar las excepciones en la subclase.
Aunque es til clasificar las excepciones en categoras y manejar una categora
particular de excepciones, algunas veces la situacin puede demandar que cada
excepcin se maneje separadamente.
Por esto, hay dos formas en las que se puede capturar y manejar excepciones. El
primer mtodo es capturar cada excepcin separadamente, comenzando desde el nodo

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 15


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

inferior y subiendo en la jerarqua. El segundo mtodo es capturar directamente la


excepcin representada por el nodo superior.
El algoritmo para el primer mtodo de captura de excepciones, es decir, capturar cada
excepcin separadamente, es como se muestra a continuacin:

El algoritmo comienza aqu


try{
// Cdigo que puede generar la excepcin
}
catch (FileNotFoundException x1) {
//Cdigo para manejar la excepcin
}
catch (FileCorruptException x2) {
// Cdigo para manejar la excepcin
}
catch (NoPermissionOnFileException x3) {
// Cdigo para manejar la excepcin
}
catch (CannotReadException x4) {
// Cdigo para manejar la excepcin
}
catch (FileException x5) {
// Cdigo para manejar la excepcin
}
El algoritmo termina aqu
En el cdigo anterior, si la primera sentencia catch capturara FileException,
entonces todas las excepciones lanzadas, que sean sub-clases de FileException
sern capturadas justo en el primer catch. Esto no es deseable normalmente, ya que
se quiere que cada excepcin especfica sea manejada separadamente. Por esto, se
tiene a la superclase FileException como el ltimo manejador de excepcin.
El segundo mtodo de capturar excepciones, es decir, capturar la expresin del nodo
superior directamente, es como a continuacin se muestra:
El algoritmo comienza aqu
try{
// Cdigo que puede generar la excepcin
Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 16

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

}
catch (FileException x) {/*
// Cdigo para manejar la excepcin
}
El algoritmo termina aqu
Una vez entendidos los conceptos de excepciones, se explican ahora las excepciones
verificadas y las no verificadas.

6. Excepciones Verificadas y No Verificadas


Las excepciones verificadas son aquellas que el programador debe capturar y manejar
dentro de la aplicacin. Si el programador no captura una excepcin verificada, o no la
especifica usando la clusula throws en la declaracin del mtodo, se producir un
error en tiempo de compilacin. El programa no compilar hasta que la excepcin sea
capturada y manejada en algn punto apropiado dentro del programa.
Las excepciones no verificadas son excepciones del tiempo de ejecucin, las cuales
son detectadas por la JVM. Las excepciones no verificadas son las excepciones de la
clase RuntimeException y sus subclases que son lanzadas en un programa Java
cuando hay un problema en la JVM. A los programadores no se les exige capturar y
manejar las excepciones no verificadas.
Existen situaciones donde se sabe que el cdigo Java que se escribe puede arrojar
excepciones, pero no se est seguro del tipo de la excepcin que ser lanzada. En
estos casos, se puede simplemente capturarlas usando la clase Exception, que es la
superclase de las excepciones, y una sub-clase de la clase Throwable. No es necesario
capturar cada excepcin separadamente.
Java provee varias clases para manejar excepciones y errores. Se presentan a
continuacin.

7. La Clase Throwable y sus Clases Derivadas


La Figura 1.5 muestra la jerarqua de clases general de varias excepciones y errores
provistos en la librera de Java. La clase Throwable es la superclase de las clases
Error y Exception.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 17


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Figura 1.5: Jerarqua General de Clases de Excepciones y Errores de la Librera de Java

Los objetos de las clases Error y Exception son las excepciones lanzadas en los
programas Java. Los errores causan que los objetos Error sean lanzados y las
excepciones causan que los objetos Exception sean lanzados. Los errores son
excepciones de bajo nivel, lanzados por la JVM.
Java provee pocas clases excepcin como parte de su librera, se explican ahora
brevemente.
Los programas Java que se escriben pueden lanzar y capturar solo excepciones, y no
errores. La clase RuntimeException es un tipo especial de excepcin que indica las
excepciones ocurridas en la JVM en tiempo de ejecucin. La clase
NullPointerException es un tipo de RuntimeException que ocurre cuando un
mtodo intenta acceder a un objeto a travs de una referencia a null. No es necesario
para los programadores capturar y manejar excepciones del tiempo de ejecucin, ya
que es difcil seguirlas y capturarlas. Se ha discutido acerca de las excepciones, ahora
Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 18

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

pasando a los errores, algunos ejemplos de errores son: errores de AWT, errores de
enlace, error de hilo muerto, y error de la mquina virtual. Java tiene clases separadas
para manejar todos estos tipos de errores. AWT (Abstract Window Toolkit) ser cubierto
en el Volumen 5, Unidad 1 Componentes y Contenedores AWT.
A continuacin se resumen las posibles acciones que se pueden tomar cuando se
encuentra una excepcin en el programa.

8. Manejo de Excepciones
Los programadores pueden manejar las excepciones en cuatro formas, que son:

Ignorar las excepciones no verificadas.

Manejar las excepciones con un bloque try-catch.

Lanzar las excepciones al mtodo que invoc al actual.

Manejar las excepciones y relanzarlas al mtodo que invoc al actual.

8.1 Ignorar las Excepciones No Verificadas


Los programadores pueden o no manejar las excepciones no verificadas. El compilador
no impone ninguna restriccin en las excepciones no verificadas. Los programadores
pueden ignorarlas.
La Figura 1.6 muestra como las excepciones no verificadas pueden ser ignoradas.

Figura 1.6: Ignorando las Excepciones No Verificadas

Si no se toma ninguna accin cuando ocurre una excepcin no verificada, el mtodo en


el cual ocurre la excepcin termina. La excepcin es enviada al mtodo que llam al
primer mtodo. Esta es propagada hasta que la excepcin sea manejada o el programa
termina.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 19


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

8.2 Manejar Excepciones con el bloque try-catch


Esta es una forma estndar de manejar excepciones en Java. El bloque try-catch
intercepta la excepcin y la maneja. La excepcin potencial puede ocurrir en cualquier
lugar dentro del bloque try. Una vez que la excepcin ocurre, el control se transfiere al
bloque catch para el manejo. La Figura 1.7 ilustra esto.

Figura 1.7: Manejando Excepciones con el Bloque try-catch

En la figura, se llama al mtodo registrarEmpleado() dentro del bloque try. En


caso de que se lance EmpleadoActualExcepcion, es manejada dentro del bloque
catch. La direccin del objeto EmpleadoActualExcepcion es recibida dentro del
bloque catch para el procesamiento.

8.3 Lanzar Excepciones al Mtodo Invocante


Puede haber situaciones donde se tendr una excepcin verificada, pero no se est
seguro de que se tiene que hacer si la excepcin es capturada. En estos casos, se
puede pasar la excepcin al mtodo que llam al mtodo actual. Considere la Figura
1.8, donde el mtodo registrarEmpleado() lanza EmpleadoActualExcepcion.
En caso de que la excepcin ocurra en este mtodo, la excepcin es manejada en el
mtodo que invoc al mtodo registrarEmpleado().

Figure 1.8: Lanzando Excepciones al Mtodo Invocante

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 20

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

8.4 Manejar Excepciones y Re-lanzarlas al Mtodo Invocante


Puede haber situaciones donde se quiera capturar una excepcin, pero no se puede
resolver la raz de la causa del mismo. En estos casos, se puede capturar la excepcin,
hacer lo que se pueda para corregirla y pasar el objeto excepcin al mtodo invocante.
Esto se muestra en la Figura 1.9.

Figura 1.9: Manejar y Relanzar Excepciones al Mtodo Invocante

En el cdigo anterior, si el objeto e es modificado dentro del bloque catch, y luego


relanzado, el e modificado ser lanzado. As, un manejo parcial del error puede
realizarse, donde el objeto e puede ser modificado, y luego relanzado.
Se han visto varias formas de manejar excepciones y tambin diversos escenarios,
donde se debe adoptar un mtodo particular de manejo. Se puede decidir la forma
apropiada de manejar excepciones, sin embargo, cuando hay numerosas invocaciones
a mtodos, manejo de excepciones y bloques que lanzan excepciones, el programador
tiene que entender el flujo de las excepciones.
Se discute a continuacin el flujo de manejo de excepciones.

9. Flujo de Manejo de Excepciones


Cuando se tienen muchas invocaciones a mtodos y mtodos lanzando las excepciones
a los mtodos que los invocaron, se torna difcil entender el flujo de la excepcin.
Considere la Figura 1.10, que explica el flujo de una excepcin.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 21


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Figura 1.10: Flujo del Manejo de una Excepcin

El mtodo enemistar() es el detector de la condicin de error. En el punto de la


deteccin, crea y lanza un objeto. Un objeto, que es especificado por el 'throw', y debe
ser una subclase de la clase Throwable.
Asuma que algn mtodo invoca al mtodo cobrar(). Este a la vez llama al mtodo
prestar() dentro un bloque try-catch. La excepcin lanzada por el mtodo
prestar() es manejada por el mtodo cobrar() dado que no hay bloque catch
definido en prestar().
El mtodo prestar() invoca a enemistar(), que lanza la excepcin X. Dado que la
excepcin en enemistar() no es manejada dentro de prestar()es relanzada al
mtodo cobrar().

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 22

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Resumen
Ahora que ha completado esta unidad, usted debe ser capaz de:

Definir las excepciones y las tcnicas tradicionales para el manejo de errores.

Describir el manejo de excepciones en Java.

Diferenciar entre las excepciones verificadas y no verificadas.

Describir las sub-clases de la clase Throwable.

Describir el flujo de manejo de excepciones en Java.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 23


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Unidad 1: Examen de Autoevaluacin


1) Cules de las siguientes sentencias son verdaderas?
a) Las excepciones son eventos.
b) Los errores causan excepciones.
c) Las excepciones causan errors.
d) Todos los eventos son excepciones.
2) Cules de las siguientes opciones pueden causar excepciones?
a) Una falla de chip de memoria.
b) Un intento de dividir un entero entre cero.
c) Una referencia a una ubicacin de memoria no asignada al usuario.
d) Un intento de ejecutar una instruccin ilegal.
3) En Java, cules de las siguientes opciones son consideradas como errores?
a) Una falla de chip de memoria.
b) Un intento de dividir un entero entre cero.
c) Una referencia a una ubicacin de memoria no asignada al usuario.
d) Un intento de ejecutar una instruccin ilegal.
4) Cul de las siguientes es la clase base de todas las excepciones y errores?
a) Exception.
b) Error.
c) Throwable.
d) Ninguna de las anteriores.
5) En Java, tanto Error como Exception se derivan de la clase Throwable.
a) Verdadero
b) Falso
6) En Java, RuntimeException no necesita ser capturada ni manejada por el
programador.
a) Verdadero
b) Falso

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 24

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

7) Si A es la superclase de B, C y D, donde A, B, C y D son clases excepcin, cul es


el mensaje impreso cuando una excepcin de la clase B es lanzada cuando se
invoca al method1. (Refirase al fragmento de cdigo dado a continuacin para
responder a esta pregunta.)
try {
// metodo1 invocado aqui
}
catch(Throwable t) {
System.out.println("T");
}
catch (A a) {
System.out.println("A");
}
catch (B b) {
System.out.println("B");
}
catch (Exception e) {
System.out.println("E");
}
a) B
b) A
c) Error de compilacin
d) E
8) Las sentencias en Java dentro del bloque finally siempre sern ejecutadas ya
sea que una excepcin sea lanzada o no.
a) Verdadero
b) Falso
9) Qu pasara si throw object; es especificado y object no es un objeto
Throwable?
a) El throw ser vlido.
b) Ser convertido en un objeto Throwable y la sentencia ser ejecutada.
c) El compilador sealara un error.
d) Esto lanzara una excepcin.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 25


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

10) Cul palabra clave se usa para indicar que un mtodo lanza una excepcin?
a)

throw.

b)

thrown.

c)

throws.

d)

Ninguna de las anteriores.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 26

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Respuestas a la Unidad 1: Examen de Autoevaluacin


1) a y b
2) b
3) a, c y d
4) c
5) a
6) a
7) c
8) a
9) c
10) c

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 27


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 2: Lanzamiento y Manejo de


Excepciones
Objetivos de Aprendizaje
Al final de esta unidad, usted ser capaz de:

Mencionar las excepciones estndar en Java.

Describir el uso de la jerarqua de excepciones.

Explicar como sobrescribir mtodos que lanzan excepciones.

Crear excepciones definidas por el usuario.

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 29


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

1. Introduccin
En la Unidad 1 Manejo de Excepciones y Tipos de Excepciones, se explicaron las
excepciones, la importancia de manejar excepciones y las clases excepcin en Java. Se
mostraron las sentencias bsicas en Java try, catch y finally, que ayudan a
manejar las excepciones y tambin se discutieron las excepciones verificadas y no
verificadas.
En esta unidad, se discutirn algunos ejemplos que ilustran el manejo de las
excepciones de Java. Tambin se explicar el mtodo para definir, capturar y manejar
excepciones definidas por el usuario.
Igualmente se explic que Java provee soporte para manejar excepciones en la forma
de excepciones verificadas y no verificadas. Estas forman parte de la clasificacin
general de las excepciones estndar en Java. Java tambin le proporciona al
programador la posibilidad de definir excepciones, que son llamadas excepciones
definidas por el usuario. Antes, de proceder se explican las excepciones estndar en
Java.

2. Excepciones Estndar en Java


Se ha estudiado que las excepciones estndar son de dos tipos, verificadas y no
verificadas. Las excepciones verificadas son aquellas que el programador debe capturar
y manejar dentro de la aplicacin, las excepciones verificadas no son del sistema de
tiempo de ejecucin. Si el programador no captura una excepcin verificada usando el
bloque try-catch, o no la especifica usando la clusula throws en la declaracin del
mtodo, se arrojar un error en tiempo de compilacin. Si un cdigo puede lanzar ms
de una excepcin, entonces el cdigo debe ser colocado dentro de un bloque try y
seguido de un bloque catch para cada excepcin que puede ser lanzada. Observe el
siguiente ejemplo.
Ejemplo 2.1
El programa de este ejemplo ilustra como cada excepcin se maneja separadamente
con diferentes bloques catch.
El cdigo Java comienza aqu
1. /*Definicion de la clase ExcepcionEjemplo comienza aqui*/
2. public class ExcepcionEjemplo {
3.
/* Metodo main comienza aqui */
4.
public static void main(String[] args) {
5.
6.
7.

float miArregloFloat[] = new float[10];


int i;

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 30

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

8.
9.
10.

/* Chequear por argumento de lnea de comando */


if (args.length == 0)
System.out.println(

11.
12.
13.

"Uso invalido de ExcepcionEjemplo");


else {
try {

14.
15.
16.

i = Integer.parseInt(args[0]);
miArregloFloat[i - 1] = (float) 11.234;
System.out.println(miArregloFloat[i]);

17.
18.

} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(

19.
20.
21.

"El valor del argumento no puede exceder de 10");


} catch (NumberFormatException e) {
System.out.println(

22.
23.
24.

"El valor del argumento debe ser un numero entero");


}
}

25. }/* Metodo main termina aqui */


26. }/* Definicion de la clase ExcepcionEjemplo termina aqui */
El cdigo Java termina aqu
En este programa, primero se revisa si se tiene una entrada a travs de la lnea de
comandos usando un simple if. Un mensaje de error se muestra cuando no se tiene
entrada por la lnea de comandos. Seguidamente, se tiene un bloque try que convierte
el valor de entrada en un entero. Note que los argumentos de la lnea de comandos son
tomados como strings. El mtodo parseInt() en Integer convierte el string "10" en
el entero 10 si este valor es pasado como entrada en la lnea de comandos. Luego, se
usa el entero convertido como subndice para el arreglo miArregloFloat, y un valor
de punto flotante se le asigna al elemento i. Dos excepciones pueden ser lanzadas en
el bloque try, las cuales son capturadas por los bloques catch que siguen al bloque
try. Si la entrada no es un entero, se lanza una NumberFormatException, si el valor
de la entrada excede el 10, se lanza una ArrayIndexOutOfBoundsException. Los
mensajes que se reciben en cada caso, se muestran a continuacin.
Cuando el valor de la entrada no es un entero:
El valor del argumento debe ser un numero entero
Cuando el valor de la entrada excede el tamao del arreglo:
El valor del argumento no puede exceder de 10
Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 31


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

En este programa se pudo haber utilizado sola la superclase Exception en el bloque


catch. El tener la superclase ayuda a capturar todas las excepciones lanzadas en el
bloque try. Sin embargo, no se podr manejar cada excepcin separadamente.
Fin del Ejemplo 2.1
A continuacin se ver como usar la jerarqua de excepciones.

3. Usar la Jerarqua de Excepciones


Un bloque try puede tener cualquier cantidad de manejadores catch. Cuando se
lanza una excepcin, el control pasa al manejador catch apropiado. Cuando los
manejadores catch pertenecen a diferentes clases en una jerarqua de excepciones,
se sabe que las subclases en la jerarqua de excepciones deben ser capturadas antes
que las superclase en la jerarqua de excepciones. Si las excepciones de las
superclases son tomadas antes que las excepciones de las subclases, el compilador
generar un error. Esto, porque la superclase se refiere a un concepto de
generalizacin, mientras que la subclase representa una especializacin del mismo
concepto. As, los manejadores de excepciones deben siempre primero manejar las
excepciones en las subclases de la jerarqua. A continuacin se presenta un ejemplo.
Ejemplo 2.2
El fragmento de cdigo en el ejemplo ilustra el concepto de la jerarqua de excepciones
que se ha discutido.
El cdigo Java comienza aqu
try {
i = Integer.parseInt(args[0]);
miArregloFloat[i - 1] = (float) 11.234;
System.out.println(miArregloFloat[i]);
}catch (Exception e) {
System.out.println("Alguna excepcion ha sido capturada");
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println(
"El valor del argumento no puede exceder de 10");
}catch (NumberFormatException e) {
System.out.println(
"El valor del argumento debe ser un numero entero");
}
El cdigo Java termina aqu
Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 32

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Un error en tiempo de compilacin se genera para el cdigo anterior, porque ya se han


provisto los manejadores catch para manejar excepciones especficas. En Java, no se
permite que un manejador para una excepcin de una superclase preceda a uno de una
subclase. Sin embargo, se puede dejar que el manejador de la superclase sea el ltimo
manejador de excepciones. Esto lo muestra el siguiente cdigo:
El cdigo Java comienza aqu
catch (ArrayIndexOutOfBoundsException e) {
System.out.println(
"El valor del argumento no puede exceder de 10");
}catch (NumberFormatException e) {
System.out.println(
"El valor del argumento debe ser un numero entero");
}catch (Exception e) {
System.out.println(
"Alguna excepcion ha sido capturada");
}
El cdigo Java termina aqu
En el segmento de cdigo anterior, si se lanza ArrayIndexOutOfBoundsException,
el primer bloque catch la maneja. Si se lanza NumberFormatException, el segundo
bloque catch la maneja, y si alguna otra excepcin se lanza, es manejada por el tercer
bloque catch.
Fin del Ejemplo 2.2
Si no hay jerarqua de herencia entre las excepciones que pueden ser lanzadas en un
programa, entonces las excepciones pueden ser capturadas en cualquier orden. La
Figura 2.1 ilustra el manejo de excepciones usando un bloque try-catch. Los bloques
catch se usan para capturar EOFException, FileNotFoundException, y
ObjectStreamException. El orden en el cual estas excepciones son capturadas no
importa, porque no hay jerarqua de herencia entre estas tres excepciones ya que todas
son subclases de la clase java.io.IOException.

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 33


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Figura 2.1: Manejo de Mltiples Excepciones

Una vez tratado exhaustivamente las excepciones en Java, se discute brevemente la


clusula finally mencionada en la Unidad 1 Manejo de Excepciones y Tipos de
Excepciones. En la Unidad 1, se dijo que la clusula finally se puede usar para
manejar excepciones estndar. A continuacin, se discute como esta clusula puede
ser usada tambin para manejar excepciones definidas por el usuario.

4. La Clusula finally Revisada


En la Unidad 1- Manejo de Excepciones y Tipos de Excepciones, mostr que el bloque
finally se puede usar al final del bloque try-catch para realizar operaciones de
limpieza. El bloque finally ser ejecutado sin importar si la excepcin es lanzada o
no y an si el bloque try-catch tiene una sentencia return.
Sin embargo, no ser ejecutado si se tiene la siguiente sentencia:
System.exit(0);
En cualquiera de los bloques try o catch System.exit(0) simplemente finalizar el
programa, sin hacer ninguna operacin de limpieza. Usar el bloque finally y la
instruccin System.exit(0)juntos se considera una prctica pobre de programacin,
debido a que el control del programa nunca alcanzar el bloque finally. Se presenta
a continuacin un ejemplo para entenderlo mejor.
Ejemplo 2.3
Se escribe un programa que calcula la divisin de dos enteros que son pasados como
argumentos.

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 34

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

El cdigo Java comienza aqu


1. /*Definicion de la clase comienza aqui*/
2. public class EnteroExcepcionEjemplo {
3.
4.
5.

/* Metodo main comienza aqui */


public static void main(String[] args) {
System.out.println(

6.
7.
8.

"Invocando dividirEnteros " +


"para dividir 12 entre 3");
dividirEnteros(12, 3);

9.
10.
11.

System.out.println(
"Invocando dividirEnteros " +
"para dividir 12 entre 0");

12.
13.
14.

dividirEnteros(12, 0);
}/* Metodo main termina aqui */

15.
16.
17.

/* Metodo dividirEnteros comienza aqui */


public static void dividirEnteros(int x, int y) {
try {

18.
19.
20.

int z = x / y;
System.out.println("Cociente: " + z);
}// Fin del bloque try

21.
22.
23.

catch (Exception e) {
System.out.println(
"Ocurrio una excepcion efectuando la division");

24.
25.

}// Fin del bloque Exception


finally {

26.
27.
28.

System.out.println(
"Ejecucion del bloque finally");
}// Fin del bloque finally

29.
}/* Metodo dividirEnteros termina aqui */
30. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
La salida del cdigo anterior ser como sigue:
Invocando dividirEnteros para dividir 12 entre 3
Cociente: 4
Ejecucion del bloque finally
Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 35


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Invocando dividirEnteros para dividir 12 entre 0


Ocurrio una excepcion efectuando la division
Ejecucion del bloque finally
Fin del Ejemplo 2.3
En este ejemplo, cuando el mtodo dividirEnteros es invocado (lnea 8) por
primera vez con los argumentos 12 y 3, el resultado de la operacin es 4 y este valor es
almacenado en z. La prxima instruccin es ejecutada y se imprime lo siguiente:
Cociente: 4
Luego la clusula finally se ejecuta, e imprime lo siguiente:
Ejecucion del bloque finally
Cuando el mtodo dividirEnteros se ejecuta por segunda vez con argumentos 12 y
0(lnea 12), se sabe que resultar en un error porque un entero se divide entre cero. En
este caso se arroja una excepcin, y por esto la prxima instruccin,
System.out.println no se ejecuta. La excepcin ser capturada por el bloque
catch y cuando la sentencia dentro del bloque catch se ejecuta, se imprime lo
siguiente:
Ocurrio una excepcion efectuando la division
Luego, el bloque finally se ejecuta y se imprime lo siguiente:
Ejecucion del bloque finally
Los mtodos que lanzan excepciones pueden tambin ser sobrescritos como los
mtodos normales en Java. Esta sobrescritura ayuda cuando las subclases proveen
una funcionalidad especfica para el mtodo. A continuacin se aprender como
sobrescribir mtodos que lanzan excepciones.

5. Sobrescribir Mtodos que Lanzan Excepciones


Cuando la superclase y su subclase tienen mtodos con el mismo nombre, nmero,
tipo de argumentos y orden, la subclase esta sobrescribiendo el mtodo en la
superclase. Por esto, cuando se invoca este mtodo desde un objeto de la subclase,
solo el mtodo que fue declarado en la subclase ser ejecutado. El mtodo declarado
en la superclase est oculto.
Cuando una subclase sobrescribe un mtodo que lanza una excepcin declarada en su
superclase, la subclase puede hacer una de las siguientes opciones en el mtodo
sobrescrito:

El mtodo en la subclase puede lanzar el mismo tipo de excepciones lanzadas


en el mtodo de la superclase.

El mtodo en la subclase puede lanzar subclases de las excepciones lanzadas


por el mtodo en la superclase.

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 36

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Por ejemplo, asuma que la excepcin A tiene las subclases B y C. Otra clase llamada
Super en su mtodo miMetodo lanza una excepcin de tipo A. Cualquier clase
derivada de Super, cuando sobrescriba miMetodo, puede lanzar una excepcin de tipo
A, o las subclases de A, que son B y C. Las subclases de Super no pueden lanzar
ninguna otra excepcin en el mtodo miMetodo.
El mtodo en la subclase puede lanzar menos excepciones que el mtodo en la
superclase o puede no lanzar ninguna excepcin.
Sin embargo, el mtodo declarado en la subclase no puede lanzar una excepcin que
sea superclase de la excepcin lanzada en el mtodo de la superclase. Se presenta el
Ejemplo 2.4 para entender esto claramente.
Nota: Estas reglas aplican solo para excepciones verificadas, y solo para mtodos
sobrescritos no sobrecargados.
Ejemplo 2.4
El siguiente cdigo ilustra el concepto de lanzar excepciones en superclase y subclases.
El cdigo Java comienza aqu
1.
2.
3.

import javax.naming.LinkException;
import javax.naming.NamingException;

4.
5.
6.

/*Definicion de la clase SuperClase comienza aqui*/


class SuperClase{
/* Metodo miMetodo comienza aqui */

7.
8.
9.

public static void miMetodo(int a)


throws LinkException{

10.
}/* Metodo miMetodo termina aqui */
11. }/* Definicion de la clase SuperClase termina aqui */
12.
13. /*Definicion de la clase SubClase comienza aqui*/
14. public class SubClase extends SuperClase{
15.
/* Metodo miMetodo comienza aqui */
16.
17.

public static void miMetodo(int a)


throws NamingException{

18.
19.
20.

}/* Metodo miMetodo termina aqui */

21.

/* Metodo main comienza aqui */

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 37


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

22.
23.
24.
25.
26.
27.

Gua del Estudiante

public static void main(String[] args) {


SubClase sc = new SubClase();
try {
sc.miMetodo(10);
}// Fin del bloque try
catch (Exception e) {

28.
}// Fin del bloque catch
29.
}/* Metodo main termina aqui */
30. }/* Definicion de la clase SubClase termina aqui */
El cdigo Java termina aqu
Este programa no compilar (lnea 16 en SubClase) porque el mtodo miMetodo en
SuperClase lanza LinkException, y el mtodo miMetodo en SubClase lanza
NamingException, que es superclase de LinkException.
Suponga que el mtodo miMetodo en SuperClase lanza NamingException, y el de
SubClase lanza LinkException, entonces el programa compilar. Vea las lneas
que cambiaran en el ejemplo anterior:
El cdigo Java comienza aqu
.
.
1. /*Definicion de la clase SuperClase comienza aqui*/
2. class SuperClase{
3.
/* Metodo miMetodo comienza aqui */
4.
5.

public static void miMetodo(int a)


throws NamingException{

6.
7.
}/* Metodo miMetodo termina aqui */
8. }/* Definicion de la clase SuperClase termina aqui */
9.
10. /*Definicion de la clase SubClase comienza aqui*/
11. public class SubClase extends SuperClase{
12.
13.
14.

/* Metodo miMetodo comienza aqui */


public static void miMetodo(int a)
throws LinkException{

15.
16.
.

}/* Metodo miMetodo termina aqui */

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 38

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

.
El cdigo Java termina aqu
Asuma que el mtodo miMetodo en SubClase no lanza ninguna excepcin. An as, el
programa compila, ya que el mtodo sobrescrito puede lanzar menos nmero de
excepciones o ninguna excepcin. Esto se ilustra en el siguiente fragmento de cdigo:
El cdigo Java comienza aqu
.
.
1. /*Definicion de la clase SuperClase comienza aqui*/
2. class SuperClase{
3.
/* Metodo miMetodo comienza aqui */
4.
public static void miMetodo(int a)
5.
throws LinkException{
6.
7.

}/* Metodo miMetodo termina aqui */

8. }/* Definicion de la clase SuperClase termina aqui */


9.
10. /*Definicion de la clase SubClase comienza aqui*/
11. public class SubClase extends SuperClase{
12.
/* Metodo miMetodo comienza aqui */
13.
14.
15.

public static void miMetodo(int a){


}/* Metodo miMetodo termina aqui */

.
.
El cdigo Java termina aqu
En el programa anterior, aunque miMetodo(), definido en la clase SubClase, no
lanza ninguna excepcin, el programa compila.
Fin del Ejemplo 2.4
Se discute a continuacin como las excepciones definidas por el usuario pueden ser
creadas para adaptarse a los programas.

6. Crear Excepciones Definidas por el Usuario


Cuando se crean clases propias en Java, se elaboran excepciones propias o
personalizadas para lanzar, capturar y manejar. Se pueden escribir clases de
Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 39


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

excepciones propias para adaptar su comportamiento. En Java, las excepciones se


pueden crear para adaptarlas a nuestras necesidades de programacin. Tambin es
posible crear una jerarqua de excepciones. Para crear una excepcin, primero se tiene
que declarar una clase que sea subclase de la clase Exception. El constructor de la
nueva clase excepcin que se crea invoca al constructor de su superclase (la clase
Exception). En la Figura 2.4, se ilustra que la clase MiExcepcion es la clase
excepcin que se crea, esta clase extiende de la clase Exception. El constructor de
MiExcepcion solamente invoca al constructor de su superclase, la clase Exception.

public class MiExcepcion extends Exception


{
public MiExcepcion(String mensaje)
{
super(mensaje);
}
//Esto es, ahora tiene su propia excepcion.
//Sin embargo, todavia falta un poco mas por hacer
}

Figura 2.2: Creando Una Clase Excepcin Definida por el Usuario

Se entiende mejor esto con un ejemplo.


Ejemplo 2.5
El siguiente programa crea tres excepciones, son estas: MiBaseExcepcion,
MiSubExcepcion y MiProximaExcepcion, que heredan de la clase Exception.
El cdigo Java comienza aqu
1. /*Definicion de la clase MiBaseExcepcion comienza aqui*/
2. class MiBaseExcepcion extends Exception{
3.
4.

/* Constructor MiBaseExcepcion comienza aqui */


public MiBaseExcepcion() {

5.
6.
7.

super();
}/* Constructor MiBaseExcepcion termina aqui */

8.
9.
10.

/* Constructor MiBaseExcepcion comienza aqui */


public MiBaseExcepcion(String s) {
super(s);

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 40

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

11.
}/* Constructor MiBaseExcepcion termina aqui */
12. }/* Definicion de la clase MiBaseExcepcion termina aqui */
13.
14. /*Definicion de la clase MiSubExcepcion comienza aqui*/
15. public class MiSubExcepcion extends MiBaseExcepcion{
16.
/* Constructor MiSubExcepcion comienza aqui */
17.
18.
19.

public MiSubExcepcion() {
super();
}/* Constructor MiSubExcepcion termina aqui */

20.
21.

/* Constructor MiSubExcepcion comienza aqui */

22.
23.
24.

public MiSubExcepcion(String s) {
super(s);
}/* Constructor MiSubExcepcion termina aqui */

25. }/* Definicion de la clase MiSubExcepcion termina aqui */


26.
27. /*Definicion de la clase ProximaExcepcion comienza aqui*/
28. class ProximaExcepcion extends Exception {
29.
/* Constructor ProximaExcepcion comienza aqui */
30.
public ProximaExcepcion() {
31.
32.
33.

super();
}/* Constructor ProximaExcepcion termina aqui */

34.
35.
36.

/* Constructor ProximaExcepcion comienza aqui */


public ProximaExcepcion(String s) {
super(s);

37.
}/* Constructor ProximaExcepcion termina aqui */
38. }/* Definicion de la clase ProximaExcepcion termina aqui */
El cdigo Java termina aqu
Aqu, se tiene tres excepciones creadas, MiSubExcepcion es subclase de
MiBaseExcepcion, que a su vez es subclase de Exception. Por esto,
MiSubExcepcion es indirectamente una subclase de la clase Exception.
MProximaExcepcion es una subclase directa de la clase Exception.
Fin del Ejemplo 2.5

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 41


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

7. Ms de Excepciones Definidas por el Usuario


A continuacin se presentan otros ejemplos. Se usarn las clases
InputStreamReader y BufferedReader en los ejemplos que siguen. Estas dos
clases forman parte del paquete java.io y sern estudiadas en detalle en el Volumen
4, Unidad 1 Archivos y Flujos. Seguidamente, se dar una breve explicacin de estas
clases ya que consisten en un mtodo mejor para leer datos de consola que usar
simplemente el mtodo System.in.read(). La clase InputStreamReader lee bytes
y los convierte en caracteres. Esta clase provee un puente entre flujos de bytes y
caracteres. La clase BufferedReader almacena caracteres conforme los lee de un
flujo de entrada de caracteres.
Para crear un objeto InputStreamReader, se necesita un objeto InputStream como
un argumento para el constructor de InputStreamReader. El InputStream que se
puede pasar al constructor de InputStreamReader es System.in. Para crear un
objeto de BufferedReader, se necesita un objeto de la clase Reader para el
constructor de BufferedReader. Dado que InputStreamReader lee bytes, y los
convierte en caracteres, se puede pasar un objeto de InputStreamReader como
argumento al constructor de BufferedReader.
Se presenta un extracto de cdigo para entender bien este concepto:
// Crear un objeto de InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
Se pueden combinar las dos sentencias anteriores como sigue:
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
System.in se pasa como parmetro al constructor de InputStreamReader, que a
su vez es el parmetro para el constructor de BufferedReader. Una vez creado un
objeto BufferedReader, se pueden leer caracteres de consola usando el mtodo
readLine(), como sigue:
br.readLine();
Esta instruccin retorna caracteres que pueden ser convertidos a un entero usando el
mtodo parseInt() de la clase Integer como sigue:
total =Integer.parseInt(br.readLine()); // total es un int
Usar BufferedReader para leer datos es una buena alternativa en vez de usar
System.in.read().
Ejemplo 2.6

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 42

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Tmese el ejemplo de la clase Stack. Las principales operaciones que se hacen con
una pila son push cuando se coloca un elemento en la pila y pop cuando se toma el
elemento que est en el tope de la pila. Java provee excepciones estndar para indicar
las excepciones que podran ser lanzadas durante las operaciones de push y pop.
Defnase un mtodo llamado top, que se usa para obtener el elemento del tope de la
pila sin removerlo de la pila. Se debe lanzar una excepcin si se intenta obtener el
elemento en el tope de una pila vaca. Se escribe una clase propia de excepcin
(PilaVaciaExcepcion), que ser lanzada cuando se intenta obtener el elemento tope
de una pila vaca. El siguiente programa ilustra esto:
El cdigo Java comienza aqu
1. import java.io.BufferedReader;
2. import java.io.IOException;
3. import java.io.InputStreamReader;
4. import java.util.Stack;
5.
6. /*Definicion de la clase PilaVaciaExcepcion comienza aqui*/
7. class PilaVaciaExcepcion extends Exception{
8.
/* Constructor PilaVaciaExcepcion comienza aqui */
9.
10.
11.

public PilaVaciaExcepcion() {
System.out.println("La pila esta vacia");
}/* Constructor PilaVaciaExcepcion termina aqui */

12. }/* Definicion de la clase PilaVaciaExcepcion termina aqui */


13.
14. /*Definicion de la clase PilaEjemplo comienza aqui*/
15. public class PilaEjemplo extends Stack {
16.
/* Metodo top comienza aqui */
17.
public void top(PilaEjemplo pe)
18.
19.
20.

throws PilaVaciaExcepcion{

21.
22.

throw new PilaVaciaExcepcion();


}else{

23.
24.
25.

Integer a = (Integer) pe.pop();


System.out.println(a);

26.
27.
28.

if (pe.isEmpty()){

}
}/* Metodo top termina aqui */
/* Metodo main comienza aqui */

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 43


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

29.
30.
31.
32.
33.
34.

Gua del Estudiante

public static void main(String[] args) {


int total, numero;
PilaEjemplo pila = new PilaEjemplo();
try {
BufferedReader br = new BufferedReader(

35.
36.
37.

new InputStreamReader(System.in));
System.out.println(
"Ingrese la cantidad de elementos de la pila");

38.
39.

total = Integer.parseInt(br.readLine());

40.
41.
42.

if (total != 0) {
System.out.println("Ingrese los numeros");

43.
44.
45.

while (total > 0) {


numero = Integer.parseInt(br.readLine());
pila.push(new Integer(numero));

46.
47.
48.

total--;
}

49.
50.
51.

System.out.print(
"El elemento que esta en el " +
"tope de la pila es: ");

52.
53.
54.

/* Llamada a funcion para obtener


un elemento del tope de la pila */

55.
56.
57.

}
} catch (PilaVaciaExcepcion pv) {

58.
59.
60.

System.out.println(pv);
} catch (IOException e) {
e.printStackTrace();

61.
62.

} catch (NumberFormatException e) {
System.out.println("Valor invalido");

63.
64.
65.

pila.top(pila);

System.exit(0);
}
}/* Metodo main termina aqui */

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 44

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

66. }/* Definicion de la clase PilaEjemplo termina aqui */


El cdigo Java termina aqu
El cdigo es autoexplicativo. Ilustra el mtodo para definir una excepcin definida por el
usuario. Esto se hace derivando de la clase predefinida Exception.
Fin del Ejemplo 2.6
A continuacin se explica el uso de la clusula throws con excepciones definidas por
el usuario.

8. La Clusula throws Revisada


Se requiere que un mtodo Java especifique las excepciones que puede lanzar, que no
son capturadas ni manejadas. Adems de manejar excepciones estndar, la clusula
throws se usa tambin para manejar excepciones definidas por el usuario.
Considere dos excepciones: ExcepcionA y ExcepcionB, en donde la ExcepcionA
es la superclase de ExcepcionB. Considere un mtodo prueba() en la clase
SuperClaseDePrueba.
SuperClaseDePrueba
es
la
superclase
de
SubClaseDePrueba. El mtodo prueba() declarado en SuperClaseDePrueba
puede lanzar ExcepcionB, ExcepcionA o no lanzar ninguna excepcin. Asuma que
el mtodo prueba() est sobrescrito en
SubClaseDePrueba. Si el mtodo
prueba() declarado en SuperClaseDePrueba lanza la ExcepcionA: entonces el
mtodo sobrescrito en SubClaseDePrueba puede lanzar ExcepccionA, ExcepcionB
o no lanzar ninguna excepcin; esto se debe a que el mtodo que sobrescribe slo
puede lanzar la excepcin lanzada por el mtodo en la superclase o una subclase de la
excepcin, o en ltima instancia, no lanzar ninguna excepcin. Esto se muestra en la
Figura 2.3.

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 45


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Figura 2.3: Herencia y la Clusula throws

Un mtodo puede capturar una excepcin especfica, manejarla y lanzar la misma


excepcin de nuevo desde el bloque catch. An en tal caso, se requiere que el mtodo
especifique la excepcin usando la clusula throws. La Figura 2.4 muestra un mtodo
algunMetodo() que captura AlgunaExcepcion usando un bloque catch, maneja la
excepcin y relanza AlgunaExcepcion desde el bloque catch. Aqu,
algunMetodo() especifica AlgunaExcepcion en su declaracin.

Figura 2.4: Especificando Excepciones que son Relanzadas

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 46

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

En la seccin anterior se vio como la clusula throws se puede usar para manejar
excepciones definidas por el usuario. Antes de seguir examinando la definicin de
excepciones en clases definidas por el usuario, se presenta una breve discusin sobre
usar clases excepcin en Java con un ejemplo.
Recuerde que todas las excepciones son subclases de la clase Throwable. Existen
algunas cosas que se deben tener en cuenta cuando se usa la jerarqua de
excepciones. Considere el Ejemplo 2.7.
Ejemplo 2.7
Escriba un programa que usa la jerarqua de excepciones, para entender los aspectos
involucrados en esto.
El cdigo Java comienza aqu
1. /*Definicion de la clase MiBaseExcepcion comienza aqui*/
2. class MiBaseExcepcion extends Exception{
3.
/* Constructor MiBaseExcepcion comienza aqui */
4.
public MiBaseExcepcion() {
5.
6.
7.

super();
}/* Constructor MiBaseExcepcion termina aqui */

8.
9.

/* Constructor MiBaseExcepcion comienza aqui */


public MiBaseExcepcion(String s) {

10.
super(s);
11.
}/* Constructor MiBaseExcepcion termina aqui */
12. }/* Definicion de la clase MiBaseExcepcion termina aqui */
13.
14. /*Definicion de la clase MiSubExcepcion comienza aqui*/
15. class MiSubExcepcion extends MiBaseExcepcion{
16.
17.
18.

/* Constructor MiSubExcepcion comienza aqui */


public MiSubExcepcion() {
super();

19.
20.
21.

}/* Constructor MiSubExcepcion termina aqui */

22.
23.
24.

public MiSubExcepcion(String s) {
super(s);
}/* Constructor MiSubExcepcion termina aqui */

/* Constructor MiSubExcepcion comienza aqui */

25. }/* Definicion de la clase MiSubExcepcion termina aqui */


Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 47


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

26.
27. /*Definicion de la clase ExcepcionEjemplo comienza aqui*/
28. public class ExcepcionEjemplo {
29.
30.
31.
32.
33.
34.

/* Metodo metodo1 comienza aqui */


public static void metodo1(int i) {
try {
metodo2(i);
} catch (MiBaseExcepcion e) {
System.out.print("MiBaseExcepcion: ");

35.
36.

System.out.println(e.getMessage());
System.out.println("Manejado en el metodo1");

37.
38.
39.

}/* Metodo metodo1 termina aqui */

40.
41.
42.

/* Metodo metodo2 comienza aqui */


public static void metodo2(int i)
throws MiBaseExcepcion {

43.
44.
45.

int resultado;
try {

46.
47.
48.

System.out.println("i = " + i);


resultado = metodo3(i);
System.out.print("metodo3(i) = " + resultado);

49.
50.
51.

} catch (MiSubExcepcion e) {
System.out.print("MiSubExcepcion: ");
System.out.println(e.getMessage());

52.
53.
54.

System.out.println("Manejado en el metodo2");
} finally {
System.out.print("\n");

55.
56.
57.

}
}/* Metodo metodo2 termina aqui */

58.
59.

/* Metodo metodo3 comienza aqui */


public static int metodo3(int i)

60.
61.
62.

throws MiBaseExcepcion, MiSubExcepcion {


if (i < 0)

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 48

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

63.
64.
65.

Core Java

throw new MiBaseExcepcion("El valor es muy bajo");


else if (i > 99)
throw new MiSubExcepcion("El valor es muy alto");

66.
67.
68.

else
return i + i;
}/* Metodo metodo3 termina aqui */

69.
70.
71.

/* Metodo main comienza aqui */


public static void main(String[] args) {

72.
73.

try {
metodo1(99);

74.
} catch (Exception e) {}
75.
}/* Metodo main termina aqui */
76. }/* Definicion de la clase ExcepcionEjemplo termina aqui */
El cdigo Java termina aqu
En el programa anterior, MiBaseExcepcion define dos constructores una que no
toma parmetros, y otro que toma un parmetro de tipo String. La excepcin
MiSubExcepcion que es subclase de MiBaseExcepcion sobrescribe los dos
constructores de MiBaseExcepcion.
La clase ExcepcionEjemplo define tres mtodos: metodo1(), metodo2() y
metodo3(). metodo1() invoca a metodo2() que a su vez invoca a metodo3().
metodo3()
lanza
dos
excepciones,
llamadas,
MiBaseExcepcion
y
MiSubExcepcion. La excepcin MiSubExcepcion, que es lanzada por metodo3(),
es manejada por metodo2(). La excepcin MiBaseExcepcion que es lanzada por
metodo3() se pasa a metodo2(), que a su vez la pasa a metodo1(), que finalmente
maneja la excepcin.
Si metodo2() manejara MiBaseExcepcion, entonces manejara ambas
MiBaseExcepcion y MiSubExcepcion cuando metodo3() lance estas excepciones.
En este caso las excepciones no se pasarn a metodo1().
Fin del Ejemplo 2.7

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 49


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Resumen
Ahora que ha completado esta unidad, usted ser capaz de:

Mencionar las excepciones estndar en Java.

Describir el uso de la jerarqua de excepciones.

Explicar como sobrescribir mtodos que lanzan excepciones.

Crear excepciones definidas por el usuario.

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 50

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 2: Examen de Autoevaluacin


1) Cul de las siguientes no son excepciones del tiempo de ejecucin (runtime
exceptions?
a) Excepciones no verificadas.
b) Excepciones definidas por el usuario.
c) Excepciones verificadas.
d) Ninguna de las anteriores.
2) La clusula try/catch debe intentar ____________________.
a) Capturar primero la excepcin ms genrica.
b) Capturar primero la excepcin menos genrica.
c) Capturar las excepciones en cualquier orden, pero capturarlas todas.
d) Ninguna de las anteriores.
3) Si hay un System.exit(0); dentro de un bloque try-catch
entonces____________.
a) Las sentencias dentro del finally todava sern ejecutadas.
b) El programador puede especificar si las sentencias en el finally deben ser
ejecutadas.
c) Es un error, dado que no se puede colocar esta sentencia all.
d) Las sentencias dentro del finally no sern ejecutadas.
4) Un mtodo que sobrescribe en una subclase puede lanzar solo excepciones
declaradas en su clase padre o hijas de las excepciones declaradas en su clase
padre. Cundo es verdadero esto?
a) Cuando existen mtodos sobrescritos o mtodos sobrecargados.
b) Cuando slo son mtodos sobrescritos y no mtodos sobrecargados.
c) Cuando el programador establece explcitamente que el compilador ignore el
error potencial.
d) Ninguna de las anteriores.
5) Cul de las siguientes es una declaracin correcta para una clase excepcin
definida por el usuario?
a) class A extends B {}
b) class A extends B implements Exception {}
c) class A extends Exception {}
d) class A extends Exception implements B {}

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 51


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

6) Qu indica la clusula throws de un mtodo a los programadores cliente?


a) Las excepciones que no han sido tomadas en cuenta.
b) Las excepciones con las que deber tratar cuando invoque al mtodo.
c) Las excepciones que puede ignorar cuando invoque al mtodo.
d) Ninguna de las anteriores.
7) Un mtodo puede capturar una excepcin especfica, manejarla y lanzar la misma
excepcin de nuevo desde el bloque catch.
a) Verdadero
b) Falso
8) Cul es el primer paso para crear una excepcin definida por el usuario?
a) Declarar una clase, crear una subclase de esa clase, que implemente una
clase Exception.
b) Declarar una clase Exception.
c) Declarar el constructor de la clase Exception.
d) Declarar una clase que sea subclase de la clase Exception.
9) Un bloque try-catch debe siempre estar seguido por una clusula finally.
a) Verdadero
b) Falso
10) La clusula throws est disponible para indicar que un mtodo puede
actualmente lanzar una excepcin.
a) Verdadero
b) Falso

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 52

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Respuestas a la Unidad 2: Examen de Autoevaluacin


1) c
2) b
3) d
4) b
5) c y d
6) b
7) a
8) d
9) b
10) a

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 53


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 3: Laboratorio de Lanzamiento y


Manejo de Excepciones
Objetivos de Aprendizaje

Manejar excepciones.

Usar las clusulas throw y match.

Escribir excepciones definidas por el usuario.

Libro 2: Core Java

Volumen 3: Manejo de Excepciones 55


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Ejercicios de Laboratorio
1) Escriba un programa en Java que tenga una clase abstracta llamada Cuenta. Esta
clase debe tener los siguientes miembros:
private int id;
private float saldo;
abstract void depositar(float monto) throws
MontoAnormalException;
abstract void retirar(float monto) throws
MontoInsuficienteException;
El programa debe tener tambin dos clases concretas llamadas
CuentaCorriente y CuentaAhorro que son subclases de la clase Cuenta. Los
objetos de la clase CuentaCorriente pueden llegar a tener el saldo negativo
luego de un retiro, al contrario de los objetos de la clase CuentaAhorro que no
pueden llegar a tener saldo negativo. Las clases MontoAnormalException y
MontoInsuficienteException son clases excepciones que deben ser
manejadas en el programa.
Debe escribir una clase Principal que permita crear instancias de
CuentaCorriente y CuentaAhorro para verificar el manejo correcto de las
excepciones.
Recomendaciones tiles:

Escriba una clase llamada Cuenta que defina los miembros mencionados y
mtodos que permitan acceder a las variables private (geter y seter).
El mtodo depositar() acepta un dato float que representa el monto que se
desea depositar en la cuenta. Este mtodo lanza MontoAnormalException
como advertencia cuando el monto a depositar excede los 10 millones de Bs.
El mtodo retirar() acepta una dato float que representa el monto que se
desea
retirar
de
la
cuenta.
Este
mtodo
lanza
MontoInsuficienteException cuando el monto a retirar es mayor al saldo
disponible en la cuenta.
Crear dos clases excepciones llamadas MontoInsuficienteException y
MontoAnormalException que tengan mensajes acordes con el evento
sucedido.
Crear dos subclases de Cuenta llamadas CuentaCorriente y
CuentaAhorro. Estas clases deben ser concretas, para esto deben
implementar los mtodos abstractos de su superclase.
La clase CuentaCorriente debe permitir crear instancias de ella en donde sea
posible tener saldos negativos sin lanzar ninguna excepcin.

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 56

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

La clase CuentaAhorro debe permitir crear instancias de ella en donde no sea


posible tener saldos negativos, cuando se intente retirar algn monto mayor al
saldo disponible debe lanzar MontoInsuficienteException.
Crear una clase llamada Principal que tenga el mtodo main y en el cual se
creen instancias de CuentaAhorro y CuentaCorriente para verificar el
manejo correcto de las excepciones.

2) Escriba un programa en Java que tenga una clase llamada Autentica. Esta clase
tiene los nombres de usuario y sus correspondientes palabras claves guardadas
en arreglos String (declarados private). Tambin tiene una variable boolean,
accesoPermitido, cuyo valor por defecto es false. Existe un mtodo llamado
chequearClave() que verifica la palabra clave ingresada contra el nombre de
usuario. Si la palabra clave ingresada es correcta, entonces imprime
Autenticacin Verificada. Acceso al Usuario Permitido en la
salida estndar cambia el valor de accesoPermitido a true.
Si la palabra clave ingresada es incorrecta entonces accesoPermitido se hace
false y se lanza una excepcin llamada PropiedadPrivadaExcepcion.
PropiedadPrivadaExcepcion es una excepcin definida por el usuario. La
clase Usuario instancia la clase Autentica, e invoca al mtodo
chequearClave()para validar la palabra clave a fin de obtener acceso a
DatoSecreto. Los datos en la clase DatoSecreto solo puede ser accedidos
cuando accesoPermitido de Autentica es true, de otra forma se lanza una
excepcin AlertaDeIntrusoExcepcion, tambin definida por el usuario.
Ambas
excepciones
PropiedadPrivadaExcepcion
y
AlertaDeIntrusoExcepcion tienen informacin que puede ser usada por
Usuario cuando son capturadas.
Recomendaciones tiles:

Escriba clases excepcin llamadas PropiedadPrivadaExcepcion


AlertaDeIntrusoExcepcion que extiendan de la clase Exception.

Escriba una clase llamada DatoSecreto que tenga una variable private y
mtodos para obtener y asignar valor a la variable private.

Escriba una clase Autentica y dentro de ella, declare dos arreglos de String
que sean inicializadas con nombres de usuario y sus correspondientes palabras
clave.

Declare una variable boolean, accesoPermitido inicializada en false.

Defina un mtodo, chequearClave que revise si un nombre de usuario y


palabra clave recibidos concuerdan con los del arreglo de String.

Escriba una clase, Usuario que acepte un nombre de usuario y una palabra
clave y use el mtodo chequearClave para autenticar al usuario.

Libro 2: Core Java

Volumen 3: Manejo de Excepciones 57


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Si el mtodo chequearClave retorna true, entonces se imprime


Autenticacin verificada. Acceso al Usuario Permitido en la salida estndar y a
la variable accesoPermitido se le asigna true.

Si
el
mtodo
chequearClave
retorna
PropiedadPrivadaExcepcion es lanzada.

Si la variable private en DatoSecreto se


accesoPermitido
es
false,
se
lanza
AlertaDeIntrusoExcepcion

3)

la

false,

excepcin

accede cuando
la
excepcin

Escriba un programa en Java que invierta una cadena dada. Si la cadena original
y la cadena invertida son iguales, entonces lanza una excepcin Palindrome,
que es una excepcin definida por el usuario.

Recomendaciones tiles:

Escriba una clase llamada PalindromeExcepcion que extiende de la clase


Exception.

Escriba una clase CadenaInvertida que tenga una variable String


inicializada con un valor string.

Forme un arreglo de caracteres de la variable String

Invierta el arreglo de caracteres y forme un String del arreglo invertido.

Compare la variable String inicial y la variable String obtenida de invertir el


arreglo de caracteres usando el mtodo equals().

Si el mtodo equals() retorna true, imprimir Es palndrome en la salida


estndar, sino lanzar PalindromeExcepcion.

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 58

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Volumen 4: Facilidades de Entrada /


Salida

Libro 2: Core Java

Volumen 4: Facilidades de Entrada / Salida 59


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 1: Archivos y Flujos


Objetivos de Aprendizaje
Al final de esta unidad, usted ser capaz de:

Entender la clase File.

Describir FileDescriptor.

Conocer acerca de los flujos.

Explicar los diferentes tipos de flujos de caracteres.

Explicar los diferentes tipos de flujos de bytes.

Mencionar la forma de trabajo con archivos de acceso aleatorio.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 61


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

1. Introduccin
Esta unidad se ocupa de la entrada y salida en Java.
La mayora de las aplicaciones requieren de datos que sean ledos de una fuente
externa o datos que sean almacenados en una fuente externa. Los archivos se usan
para almacenar, leer y escribir datos. Para hacer esto, primero se debe acceder a los
archivos, la unidad trata con dos categoras de clases, que estn relacionadas con
archivos:

Archivos.

Flujos.

Las clases relativas a los archivos trabajan con el sistema de archivos en la


computadora. Los flujos, por otra parte, ayudan en funciones relativas a archivos como
leer del archivo, escribir datos al archivo, leer y escribir datos sobre la red, etc.
Imagine un flujo como un tubo donde es posible leer o escribir bytes y/o caracteres. No
importa lo que pueda haber en el otro extremo del tubo: puede ser un teclado, un
monitor, un archivo, un proceso, una conexin TCP/IP o un objeto Java.
Todas las clases que manejan la entrada y salida de datos estn disponibles en el
paquete java.io. La Figura 1.1 da una visin general de algunas de las clases
disponibles en el paquete java.io.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 62

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Figura 1.1: Clases para Entrada/Salida en el Paquete java.io

De la Figura 1.1, se puede notar lo siguiente:

File,
FileDescriptor,
RandomAccessFile,
ObjectStream,
OutputStream, Reader y Writer derivan de la clase Object.

Libro 2: Core Java

InputStream,

Unidad 1: Archivos y Flujos 63


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Las clases InputStream, OutputStream, Reader y Writer tienen clases derivadas


para realizar actividades especficas de entrada/salida.

Se estudiarn algunas de las clases de la figura en esta unidad, se comienza el tema


con entrada/salida usando archivos.

2. Archivos
Java provee soporte a archivos usando tres clases, llamadas, File, FileDescriptor
y RandomAccessFile para usar el sistema de archivos en una computadora. A
continuacin se explicar primero la clase File.

2.1 La Clase File


Los archivos son un mecanismo usado para almacenar informacin. Existen varias
categoras de archivos, dependiendo del tipo de informacin que es almacenada y el
sistema de archivos que se usa depende del sistema de operacin usado en la
computadora.
Una categora particular de archivos puede, tpicamente, ser almacenada bajo un
nombre de directorio. El nombre de directorio es un identificador que se usa para
localizar una categora en particular. Todos los archivos, por ejemplo, relacionados a un
proyecto en particular pueden almacenarse bajo un directorio llamado proyecto. Se
puede tener una jerarqua de directorios para almacenar varias categoras de archivos.
Java permite acceder a los archivos almacenados en el sistema de archivos local
usando la clase File, que es una representacin abstracta de los archivos y directorios
disponibles en el sistema de archivos local. Esta representacin abstracta es
independiente del sistema de operacin o del hardware en el cual la JVM se est
ejecutando. Los objetos de la clase File son inmutables, en otras palabras, una vez
que se crea un objeto File para representar una ruta particular, no se puede modificar
para apuntar a otra ruta, slo es posible asignarle una instancia diferente de la clase
File.
La clase File extiende de la clase Object e implementa las siguientes interfaces:

Serializable

Comparable

Como File implementa la interfaz Serializable, sus objetos pueden ser


serializados y deserealizados. (Refirase a la Unidad 3 Serializacin de Objetos de
este volumen para informacin detallada acerca de la serializacin/deserealizacin).
File tambin implementa la interfaz Comparable y por esto se pueden comparar dos
rutas de objetos File usando el mtodo compareTo().

Unidad 1: Archivos y Flujos

Libro 2: Core Java 64

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

A continuacin se escribe un programa simple en Java que ilustrar como crear un


objeto de la clase File y mostrar algunos datos acerca del archivo abierto, usando la
clase File.
Ejemplo 1.1
El cdigo Java comienza aqu...
1.

import java.io.File;

2.
3. /*Definicion de la clase DetalleArchivo comienza aqui*/
4. public class DetalleArchivo {
5.
/* Metodo main comienza aqui */
6.
public static void main(String[] args) {
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.

File a = new File("/home/student1/ejemplo.txt");


if (a.exists()) {
System.out.println("* * * Datos del Archivo * * *");
System.out.println("Nombre: " + a.getName());
System.out.println("Ruta Completa: " + a.getPath());
System.out.println("Directorio Padre: " + a.getParent());
System.out.println("Tamano (en Bytes): " + a.length());
} else {
System.out.println(
"Archivo: " +
a.getName() +
" no existe");

19.
}
20.
}/* Metodo main termina aqui */
21. }/* Definicion de la clase DetalleArchivo termina aqui */
El cdigo Java termina aqu
La salida del programa ser la siguiente:
* * * Datos del Archivo * * *
Nombre: ejemplo.txt
Ruta Completa: /home/student1/ejemplo.txt
Directorio Padre: /home/student1
Tamano (en Bytes): 16
Nota: El objeto File es una abstraccin de los archivos en el sistema. La creacin de
un objeto File no crear ningn archivo en el sistema de archivos.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 65


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Fin del Ejemplo 1.1


A continuacin se discuten los separadores de archivos en la ruta de archivos.

2.2 Separadores de Archivos


Los separadores de archivos son aquellos que separan los subdirectorios en la ruta.
Windows usa una barra invertida \ para separar los subdirectorios, en cambio UNIX
usa una barra / para separar los directorios. Como resultado, las rutas de archivos
lucen diferentes en cada sistema de operacin.
Por ejemplo, en el Ejemplo 1.1, se us la siguiente lnea de cdigo:
File a = new File("/home/student1/ejemplo.txt"). Para evitar el problema de los
separadores y el sistema operativo, se puede usar File.separator, que usa el
separador por omisin del sistema de operacin en el cual el programa se est
ejecutando. El cdigo anterior modificado con File.separator se da a continuacin:
File a = new File(File.separator+"home"+
File.separator+"student1"+ File.separator+"ejemplo.txt");
Este cdigo puede ser usado en ambos Windows y UNIX.
Ahora, se vern los descriptores de archivo.

2.3 La Clase FileDescriptor


Esta clase se usa para manejar flujos de entrada, salida y error especficos para la
mquina dentro de un programa Java. Esta clase tiene variables estticas como
manejadores para los siguientes tres flujos:

FileDescriptor.in

- Maneja el flujo de entrada

FileDescriptor.out

- Maneja el flujo de salida

FileDescriptor.err

- Maneja el flujo de error

Tpicamente, las aplicaciones no crean descriptores de archivo.


FileDescriptor extiende de la clase Object. Los objetos FileInputStream,
FileOutputStream, FileWriter y FileReader pueden ser creados usando el
objeto FileDescriptor como argumento. El siguiente fragmento de cdigo muestra
como un objeto FileWriter se crea usando un objeto FileDescriptor. La clase
FileWriter ser discutida en una seccin posterior. El cdigo a continuacin se usa
simplemente para mostrar el uso de la clase FileDescriptor.
Ejemplo 1.2
El cdigo Java comienza aqu
22. import java.io.FileDescriptor;
Unidad 1: Archivos y Flujos

Libro 2: Core Java 66

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

23. import java.io.FileWriter;


24.
25. /*Definicion de la clase FileDescriptorEjemplo comienza aqui*/
26. public class FileDescriptorEjemplo {
27.
/* Metodo main comienza aqui */
28.
public static void main(String[] args) {
29.
30.
31.
32.
33.
34.
35.
36.

try {
FileDescriptor fd = FileDescriptor.out;
FileWriter fw = new FileWriter(fd);
fw.write("Hola mundo!");
fw.close();
} catch (Exception e) {
e.printStackTrace();
}

37.
}/* Metodo main termina aqui */
38. }/*Definicion de la clase FileDescriptorEjemplo termina aqui*/
El cdigo Java termina aqu
El objeto fd se crea usando el manejador para el flujo de salida
FileDescriptor.out. fd y se le pasa entonces a FileWriter como argumento,
durante su instanciacin. Como resultado de compilar y ejecutar este programa se
imprime en la consola de salida la frase Hola mundo!
Fin del Ejemplo 1.2
En esta seccin se aprendi acerca de la clase FileDescriptor, ahora se continuar
con archivos que son accedidos de forma aleatoria.

2.4 Archivos de Acceso Aleatorio


El paquete java.io tiene la clase RandomAccessFile. El acceso aleatorio a archivos
se usa para leer y escribir datos en cualquier sitio en un archivo. El acceso secuencial a
archivo requiere pasar por cada lnea de datos en el archivo antes de encontrar la
informacin requerida.
Tmese un ejemplo para entender el acceso de datos aleatorio. Asuma que un archivo
tiene las siguientes lneas de datos:
Mike, 32, California
Aaron, 31, New York
Jane, 32, Ohio
Richards, 29, Texas
Libro 2: Core Java

Unidad 1: Archivos y Flujos 67


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

John, 31, Pennsylvania


Para encontrar a Richards, que es el cuarto registro en la lista, el acceso secuencial
requerir pasar a travs de los tres primeros registros. Pero usando la operacin de
seek en modo de acceso aleatorio, Richards puede ser encontrado sin pasar por los
tres primeros registros.
RandomAccessFile extiende de la clase Object e implementa las siguientes
interfaces:

DataOutput

DataInput

Los argumentos que se usan cuando se instancia una clase, ayudan a decidir si el
objeto ser usado para lectura o escritura.
La siguiente lnea de cdigo crea un RandomAccessFile que se usa para leer del
archivo entrada.txt.
new RandomAccessFile("entrada.txt", "r");
La siguiente lnea crea una clase RandomAccessFile que se usa para lectura y
escritura en el archivo salida.txt:
new RandomAccessFile("salida.txt", "rw");
El r y rw indican el modo de apertura del archivo de acceso aleatorio. Aqu r denota
slo lectura, y rw denota lectura-escritura.
La clase RandomAccessFile provee soporte para el concepto de apuntador a archivo
para indicar la ubicacin actual en el archivo. En el momento de creacin del archivo, el
puntero de archivo se establece en 0, lo que indica el inicio del archivo. Luego el
nmero de bytes que son ledos o escritos mueve el apuntador del archivo.
Esta manipulacin del apuntador a archivo se lleva a cabo en esta clase, usando los
siguientes tres mtodos: skipBytes(), seek() y getFilePointer().
El mtodo skipBytes() mueve el apuntador de archivo hacia adelante el nmero de
bytes especificado. El mtodo seek() posiciona el apuntador de archivo exactamente
antes del byte especificado. El mtodo getFilePointer() permite obtener la
ubicacin actual del apuntador a archivo. En caso de que el fin de archivo se alcance
antes de leer el nmero de bytes especificado, entonces se lanza una EOFException y
en caso de no leer o escribir un byte, entonces se lanza una IOException. Una
IOException puede ser lanzada tambin cuando un flujo est cerrado.
Ejemplo 1.3
Este programa ilustra como leer y escribir datos a un archivo de acceso aleatorio.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 68

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

El cdigo Java comienza aqu


1. import java.io.File;
2. import java.io.FileNotFoundException;
3. import java.io.IOException;
4. import java.io.RandomAccessFile;
5.
6. /*Definicion de la clase comienza aqui*/
7. public class RandomAccessFileEjemplo {
8.
final static int POSICION_CARACTER = 2;
9.
10.
11.

static String nombreArchivo = "aleatorio.txt";

12.
13.
14.

public static void main(String args[]) {


try {
RandomAccessFileEjemplo aleatorio;

/* Metodo main comienza aqui */

15.
16.
17.

aleatorio = new RandomAccessFileEjemplo();


aleatorio.escribirAlfabeto();
aleatorio.leerAlfabeto();

18.
19.
20.

} catch (Exception e) {
System.out.println(e);
}

21.
22.
23.

}/* Metodo main termina aqui */

24.
25.

public void leerAlfabeto() throws IOException {


try {

26.
27.
28.

File archivo = new File(nombreArchivo);


RandomAccessFile raf;
raf = new RandomAccessFile(archivo, "r");

29.
30.
31.

System.out.println(
"\nAlfabeto desde el archivo " +
nombreArchivo);

32.
33.
34.

long longitud = raf.length();


for (int i = POSICION_CARACTER;
i < longitud;

/* Metodo leerAlfabeto comienza aqui */

35.
36.
Libro 2: Core Java

i += 2 * POSICION_CARACTER) {

Unidad 1: Archivos y Flujos 69


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

37.
38.
39.

Gua del Estudiante

raf.seek(i);
System.out.println(raf.readChar());
}// Fin del ciclo for

40.
41.
42.

raf.close();
} catch (FileNotFoundException e) {
System.out.println("No se encuentra el archivo");

43.
44.
45.

System.exit(0);
} catch (IOException e) {
System.out.println(e);

46.
47.

}
} /* Metodo leerAlfabeto termina aqui */

48.
49.
50.

/* Metodo escribirAlfabeto comienza aqui */


public void escribirAlfabeto() throws IOException {

51.
52.
53.

File archivo = new File(nombreArchivo);


RandomAccessFile raf;
raf = new RandomAccessFile(archivo, "rw");

54.
55.
56.

System.out.println(
"Los datos a escribir en el archivo " +
nombreArchivo + " son:");

57.
58.
59.

for (int i = 65; i < 91; i++) {


raf.writeChar(i);
System.out.print((char) i + " ");

60.
61.
62.

}// Fin del ciclo for


System.out.println();
raf.close();

63.
}/* Metodo escribirAlfabeto termina aqui */
64. }/* Definicion de la clase termina aqu */
El cdigo Java termina aqu
La salida del programa anterior es como sigue:
Los datos a escribir en el archivo aleatorio.txt son:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Alfabeto desde el archivo aleatorio.txt
B
D

Unidad 1: Archivos y Flujos

Libro 2: Core Java 70

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

F
H
J
L
N
P
R
T
V
X
Z
Fin del Ejemplo 1.3
En este programa, el archivo aleatorio.txt tiene las letras de la A a la Z.
RandomAccessFile se usa para acceder en forma no secuencial cada segundo
carcter almacenado en el archivo e imprimir en la salida estndar, sin pasar por cada
carcter en forma secuencial.
Ahora que se sabe como trabajar con archivos en Java, se explican los flujos y como se
manejan en Java.

3. Flujos
La entrada/salida en Java est basada en flujos. Java trata toda la informacin,
independientemente de la fuente o el destino, como flujos. Los datos que son ledos y
escritos en un programa Java son tratados como un flujo de datos, bytes continuos de
datos que vienen y van. Estos bytes son ledos o escritos a archivos, conectores o
conexiones en Internet.
Los flujos son independientes del dispositivo.
Un flujo en Java es cualquier ruta de informacin desde la fuente al destino. Los
siguientes son algunos pares de fuentes y destinos:

Un teclado (fuente) y un monitor (destino).

Una pgina de texto en un monitor (fuente) y un archivo en un disco duro


(destino).

Un archivo en un disco duro (fuente) y un monitor (destino).

Un servidor web (fuente) y un navegador (destino).

Un teclado (fuente) y una cadena de caracteres (destino).

Un archivo de texto (fuente) y una impresora (destino).

Libro 2: Core Java

Unidad 1: Archivos y Flujos 71


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

El procesamiento de flujos en Java est bien abstrado e igualmente bien entendido.


Esto hace a Java un lenguaje ideal para comunicaciones en red, porque incluye
transferencias de datos desde la fuente hasta el destino.
Considere la Figura 1.2, que ilustra el concepto de flujos en Java.

Figura 1.2: Flujos en Java

La lectura del o escritura al flujo en Java es igual a leer o escribir a un archivo en


lenguajes como C o C++. Los pasos para realizar estas operaciones son los mismos
que en C o C++.
El algoritmo bsico para leer usando un flujo se da a continuacin:
Paso 1: Abrir un flujo de la fuente de datos en el programa Java.
Paso 2: Mientras haya datos disponibles en la fuente de datos,
leerlos.
Paso 3: Cerrar el flujo.
El algoritmo bsico para escribir usando un flujo se da a continuacin:
Paso 1: Abrir el flujo a destino de los datos en el programa Java.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 72

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Paso 2: Mientras haya datos disponibles en el programa Java,


escribirlos.
Paso 3: Cerrar el flujo.
Ambos algoritmos dan los tres pasos bsicos requeridos para lectura y escritura usando
flujos. As, cualquiera sea los tipos de datos ledos o escritos, ser fcil para los
programadores usar clases de entrada/salida de Java.
Los flujos en Java estn bien organizados y se clasifican en los siguientes dos grupos:

Flujos de Byte.

Flujos de Carcter.

Estos dos tipos de flujos permiten acceder datos de una manera secuencial.
Los flujos de byte se usan para transferir 8-bits de datos, mientras que los flujos de
caracteres trabajan con caracteres de 16-bit Unicode. Los flujos de byte son
representados en Java con las clases:

InputStream.

OutputStream.

Los flujos de caracteres son representados con las clases:

Reader.

Writer.

Java considera un enfoque internacional para los caracteres; se usan dos bytes para
representar un carcter. Las clases InputStream y OutputStream no pueden
procesar caracteres Unicode de una forma eficiente, para esto fueron creadas las
clases Reader y Writer en Java.
La Figura 1.3 muestra los flujos de byte y de carcter en Java.

Figura 1.3: Flujos de Byte y Flujos de Carcter

Libro 2: Core Java

Unidad 1: Archivos y Flujos 73


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

A continuacin se estudian cada una de estas cuatro clases, llamadas, InputStream,


OutputStream, Reader y Writer, en detalle.

4. La Clase InputStream
La clase InputStream es una clase abstracta que permite leer bytes (8-bit) de datos.
Esta clase extiende de la clase Object. Las clases que heredan de InputStream
deben implementar un mtodo que retorne el prximo byte de datos del flujo que se
est leyendo.
Las subclases de la clase InputStream se muestran en la Figura 1.4.

Figura 1.4: La Clase InputStream y sus Subclases

Se discutir acerca de ObjectInputStream en la Unidad 3 Serializacin de


Objetos, la cual se usa para de-serializar objetos durante la serializacin de objetos.
Todas las otras clases sern discutidas en esta unidad. Se comenzar con
ByteArrayInputStream.

4.1 La Clase ByteArrayInputStream


La clase ByteArrayInputStream es una de las subclases de InputStream. Se ha
mencionado que si una clase es subclase de la clase InputStream, tiene que
implementar un mtodo para devolver el prximo byte de la entrada del flujo que se est
leyendo. La clase ByteArrayInputStream provee este mtodo al tener un buffer
interno de datos y un contador que representa el prximo byte en el buffer.
El ejemplo a continuacin muestra la clase ByteArrayInputStream.
Unidad 1: Archivos y Flujos

Libro 2: Core Java 74

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Ejemplo 1.4
El ejemplo ilustra la lectura en un string que el usuario introduce y se muestra el string
usando un objeto ByteArrayInputStream.
El cdigo Java comienza aqu
1.

import java.io.ByteArrayInputStream;

2.
3. /*Definicion de la clase comienza aqui*/
4. public class ByteArrayInputStreamEjemplo {
5.
/* Metodo main comienza aqui */
6.
public static void main(String[] args) {
7.
8.
9.

String frase = "Hola mundo!";

10.
11.
12.

byte arregloBytes[] = frase.getBytes();

13.
14.
15.

ByteArrayInputStream bais;
bais = new ByteArrayInputStream(arregloBytes);

16.
17.
18.

System.out.println("ByteArrayInputStream obtuvo: ");


int caracterLeido;
Character caracter = null;

19.
20.
21.

/* Leer de ByteArrayInputStream
y mostrar en mayuscula */

22.
23.
24.

while ((caracterLeido = bais.read()) != -1){


caracter = Character.toUpperCase((char) caracterLeido);
System.out.print(caracter);

25.
26.

}
bais.reset();

/* Declaracion arreglo de byte */

/* Crear una instancia de ByteArrayInputStream */

27.
}/* Metodo main termina aqui */
28. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
La salida del programa anterior es como sigue:
ByteArrayInputStream obtuvo:
Libro 2: Core Java

Unidad 1: Archivos y Flujos 75


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

HOLA MUNDO!
Fin del Ejemplo 1.4
El programa del Ejemplo 1.4 toma el string hola mundo! como entrada, y lo lee
usando el ByteArrayInputStream y se imprime en la salida estndar usando letras
maysculas.
La prxima clase que se estudia es la FileInputStream.

4.2 La Clase FileInputStream


La clase FileInputStream se usa para leer el contenido de un archivo en forma de
bytes. Los tipos de archivos que estn disponibles dependen del sistema de archivos
usado por el sistema de operacin subyacente.
La clase FileInputStream extiende de InputStream.
Considere el ejemplo 1.5, que muestra el uso de la clase FileInputStream.
Ejemplo 1.5
El cdigo Java comienza aqu...
1.

import java.io.FileInputStream;

2. import java.io.FileNotFoundException;
3. import java.io.InputStream;
4.
5. /*Definicion de la clase comienza aqui*/
6. public class FileInputStreamEjemplo {
7.
8.
9.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

10.
11.
12.

int cantidad;
String nombreArchivo = "miArchivo.txt";
InputStream ie;

13.
14.
15.

ie = new FileInputStream(nombreArchivo);
cantidad = ie.available();
System.out.println(

16.
17.
18.

"Leyendo desde el archivo: " +


nombreArchivo);
System.out.println(

19.

"Total bytes disponibles: " +

Unidad 1: Archivos y Flujos

Libro 2: Core Java 76

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

20.
21.
22.

cantidad + "\n");
/* Mostrar los datos de byte

23.
24.
25.

disponible a la salida estandar */


for (int i = 0; i < cantidad; i++) {
System.out.print((char) ie.read());

26.
27.
28.

}
/* Cerrar el InputStream */

29.
30.

ie.close();
} catch (FileNotFoundException e) {

31.
32.
33.

System.out.println("Archivo no encontrado");
System.exit(0);
} catch (Exception e) {

34.
35.
36.

System.out.println(e);
} // Fin del bloque Exception
}/* Metodo main termina aqui */

37. }/* Definicion de la clase termina aqui */


El cdigo Java termina aqu
El contenido de miArchivo.txt es el siguiente:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
La salida del programa anterior es la siguiente:
Leyendo desde el archivo: miArchivo.txt
Total bytes disponibles: 121
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Fin del Ejemplo 1.5
En el programa anterior, se leen bytes de datos del archivo miArchivo.txt, usando
FileInputStream y se imprimen en la salida estndar.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 77


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

4.3 La Clase FilterInputStream


FilterInputStream, como el nombre sugiere, se usa para trabajar en el flujo de

entrada, manipulando los datos de entrada basado en ciertos filtros (condiciones)


definidas por el usuario. La clase FilterInputStream extiende de InputStream. La
condicin del filtro puede estar basada en varias condiciones, como leer slo caracteres
ASCII o leer los caracteres de un rango especfico, etc.
FilterInputStream se ilustra en el Ejemplo 1.5.
Ejemplo 1.6
El ejemplo muestra la creacin de un objeto FilterInputStream y su uso.
El cdigo Java comienza aqu
1. import java.io.FileInputStream;
2. import java.io.FilterInputStream;
3. import java.io.IOException;
4. import java.io.InputStream;
5.
6. /*Definicion de la clase comienza aqui*/
7. public class FilterInputStreamEjemplo
8.
extends FilterInputStream {
9.
10.
11.

/* Constructor FilterInputStreamEjemplo comienza aqui */


protected FilterInputStreamEjemplo(InputStream in) {

12.
13.
14.

super(in);
}/* Constructor FilterInputStreamEjemplo termina aqui */

15.
16.
17.

/* Metodo read comienza aqui */


public int read() throws IOException {
int valor = in.read();

18.
19.
20.
21.
22.
23.
24.
25.

/* Imprimir Alfabeto */
if ((valor >= 'A' && valor <= 'Z') ||
(valor >= 'a' && valor <= 'z'))
return valor;
/* Retorno de carro, nueva linea,

Unidad 1: Archivos y Flujos

Libro 2: Core Java 78

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

26.
27.
28.

tab, y fin de archivo */


else if (valor == 10 || valor == 13 ||
valor == 9 || valor == -1)

29.
30.
31.
32.
33.
34.

Core Java

return valor;
/* Caracteres no imprimibles */
else
return '?';

35.
36.

} /* Metodo read termina aqui */

37.
38.
39.

/* Metodo read sobrecargado comienza aqui */


public int read(byte[] datos, int inicio, int maximo)
throws IOException {

40.
41.
42.

int resultado = in.read(datos, inicio, maximo);


for (int i = inicio; i < inicio + resultado; i++) {

43.
44.
45.

/* No hacer nada con los caracteres


retorno de carro, nueva linea,

46.
47.
48.

tab, y fin de archivo */


if (datos[i] == 10 || datos[i] == 13 ||
datos[i] == 9 || datos[i] == -1)

49.
50.
51.
52.
53.
54.

;
/* Caracteres no imprimibles */
else if (datos[i] < 32 || datos[i] > 126)
datos[i] = (byte) '?';
}

55.
56.
57.

return resultado;
} /* Metodo read sobrecargado termina aqui */

58.
59.

/* Metodo main comienza aqui */

60.
61.
62.

public static void main(String[] args)


throws IOException{

Libro 2: Core Java

Unidad 1: Archivos y Flujos 79


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

63.
64.
65.

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


FilterInputStreamEjemplo fise;

66.
67.
68.

fise = new FilterInputStreamEjemplo(


new FileInputStream(args[i])
);

69.
70.
71.

while (true) {
int c = fise.read();

72.
73.

if (c == -1)
break;

74.
75.
76.

System.out.print((char) c);
}
}

77.
}/* Metodo main termina aqui */
78. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
Este programa filtra el flujo de entrada para permitir solo letras. El archivo
palabras.txt que se pasa como argumento por la lnea de comandos tiene el
siguiente contenido:
Bienvenido a IBM, este programa ilustra el uso de
FileInputStream
Al introducir el siguiente comando:
java FilterInputStreamEjemplo palabras.txt
La salida del programa ser la siguiente:
Bienvenido?a?IBM??este?programa?ilustra?el?uso?de?FileInpu
tStream
Fin del Ejemplo 1.6
El programa del Ejemplo 1.6 lee el contenido del archivo palabras.txt carcter por
carcter y los imprime en la salida estndar nicamente si son letras del alfabeto. Si
FilterInputStream lee un carcter no imprimible, el carcter es filtrado y se imprime
un signo de interrogacin (?) en la salida estndar.
A continuacin se explican las cuatro subclases de la clase FilterInputStream.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 80

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

4.4 La Clase BufferedInputStream


La clase BufferedInputStream permite que los flujos de entrada almacenen en un
buffer los bytes de datos que son ledos. Los datos ledos de los flujos usualmente no
son almacenados en un buffer. Slo cuando los datos son ledos del flujo, los prximos
datos llegan al flujo. BufferedInputStream tambin es subclase de
FilterInputStream. BufferedInputStream mantiene un arreglo que representa
el buffer interno. Cuando se leen bytes del flujo, el flujo de entrada rellena el buffer
interno con un nmero de bytes, a la vez. Esto permite lecturas ms rpidas de datos,
porque estos estn pre-almacenados.
Ejemplo 1.7
Este programa muestra el uso de BufferedInputStream para leer datos de un
archivo y cuenta la cantidad de lneas que tiene el archivo.
El cdigo Java comienza aqu
1.

import java.io.BufferedInputStream;

2. import java.io.FileInputStream;
3. import java.io.IOException;
4.
5. /*Definicion de la clase comienza aqui*/
6. public class BufferedInputStreamEjemplo {
7.
/* Metodo main comienza aqui */
8.
9.
10.

public static void main(String[] args) {


if (args.length != 1) {
System.err.println(

11.
12.
13.

"uso: BufferedInputStreamEjemplo nombreArchivo");


System.exit(1);
}

14.
15.
16.

try {
BufferedInputStream bis;

17.
18.

bis = new BufferedInputStream(


new FileInputStream(args[0])

19.
20.
21.

);
int contador = 1;
int b;

22.
23.

while ((b = bis.read()) != -1) {

Libro 2: Core Java

Unidad 1: Archivos y Flujos 81


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

24.
25.
26.

if (b == '\n')
contador++;
}

27.
28.
29.

bis.close();
System.out.println(

30.
31.
32.

"El archivo contiene " +


contador +
" lineas");

33.
34.

} catch (IOException e) {
System.err.println(e);

35.
}
36.
}/* Metodo main termina aqui */
37. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
Suponiendo que el archivo palabras.txt tenga lo siguiente:
Bienvenido a
IBM
La salida del programa anterior ser la siguiente:
El archivo contiene 2 lineas
Fin del Ejemplo 1.7
El programa anterior acepta un nombre de archivo de la lnea de comandos. Abre el
archivo especificado usando BufferedInputStream, lee el contenido del archivo,
byte a byte. Cuando se encuentra el carcter \n, el valor del contador de lneas es
incrementado. Finalmente, muestra el total de lneas en la salida estndar.

4.5 La Clase DataInputStream


Los tipos de datos primitivos usualmente tienen una representacin dependiente de la
mquina subyacente. La clase DataInputStream permite que una aplicacin lea los
tipos de datos primitivos en una forma que es independiente de la mquina.
La clase DataInputStream extiende a FilterInputStream. Representa cadenas
Unicode en un formato que es una modificacin menor del formato UTF-8. Los detalles
exactos de la representacin interna de los tipos de datos primitivos en esta clase estn
ms all del alcance de esta discusin.

Ejemplo 1.8
Unidad 1: Archivos y Flujos

Libro 2: Core Java 82

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

El cdigo Java comienza aqu


1. import java.io.BufferedInputStream;
2. import java.io.DataInputStream;
3. import java.io.FileInputStream;
4. import java.io.FileNotFoundException;
5. import java.io.IOException;
6.
7. /*Definicion de la clase comienza aqui*/
8. public class DataInputStreamEjemplo {
9.
10.
11.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

12.
13.
14.

String nombreArchivo = "miArchivo.txt";


DataInputStream in;

15.
16.
17.

in = new DataInputStream(
new BufferedInputStream(
new FileInputStream(nombreArchivo)

18.
19.
20.

)
);

21.
22.
23.

System.out.println(
"Leyendo el archivo: " +
nombreArchivo +

24.
25.

". Su contenido es: "

26.
27.
28.

+ "\n");

/* Mientras no sea el fin del archivo */


while (in.available() != 0)
System.out.print((char) in.readByte());

29.
30.
31.

} catch (FileNotFoundException e) {
System.out.println("Archivo no encontrado");
System.exit(0);

32.
33.
34.

} catch (IOException e) {
System.err.println("IOException");
}

35.
}/* Metodo main termina aqui */
36. }/* Definicion de la clase termina aqui */
Libro 2: Core Java

Unidad 1: Archivos y Flujos 83


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

El cdigo Java termina aqu


El contenido de miArchivo.txt es el siguiente:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
La salida del programa es la siguiente:
Leyendo el archivo: miArchivo.txt. Su contenido es:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Fin del Ejemplo 1.8
En el programa anterior, un DataInputStream lee el contenido de miArchivo.txt
byte por byte e imprime el byte ledo en la salida estndar.

4.6 La Clase LineNumberInputStream


Esta clase es ahora obsoleta (deprecated). La clase LineNumberInputStream puede
ser usada si se necesita el nmero de la lnea actual de los datos ledos. El nmero de
la lnea actual es incrementado cuando el flujo tiene el carcter de fin de lnea (retorno
de carro '\r', nueva lnea '\n', o retorno de carro y nueva lnea \r y \n).
LineNumberInputStream extiende de FilterInputStream.

4.7 La Clase PushbackInputStream


En los flujos vistos hasta ahora, una vez ledos los datos, son removidos del flujo. Con
la clase PushbackInputStream, es posible que un dato que es ledo del flujo sea
colocado de nuevo en el flujo.
Es til cuando se leen bytes de datos que estn delimitados por un byte especfico, que
el ltimo byte ledo pueda ser des-ledo, de forma que la prxima operacin pueda
leerlo de nuevo.
La clase PushbackInputStream extiende a la clase FilterInputStream.

Ejemplo 1.9

Unidad 1: Archivos y Flujos

Libro 2: Core Java 84

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Este programa ilustra el uso de la clase PushbackInputStream, usada con


caracteres que son ledos byte por byte de un string.
El cdigo Java comienza aqu
1. import java.io.ByteArrayInputStream;
2. import java.io.IOException;
3. import java.io.PushbackInputStream;
4.
5. /*Definicion de la clase comienza aqui*/
6. public class PushbackInputStreamEjemplo {
7.
8.
9.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

10.
11.
12.

String texto = "if (marca==75)\n" +


"resultado=distincion;\n";
byte arregloBytes[] = texto.getBytes();

13.
14.

/* Crear una instancia de ByteArrayInputStream */

15.
16.
17.

ByteArrayInputStream bais;
bais = new ByteArrayInputStream(arregloBytes);

18.
19.
20.

/* Crear una instancia de PushbackInputStream */


PushbackInputStream pis;
pis = new PushbackInputStream(bais);

21.
22.
23.

int caracter;
while ((caracter = pis.read()) != -1) {

24.
25.
26.

if (caracter == '=') {
if ((caracter = pis.read()) == '=')
System.out.print(".eq.");

27.
28.
29.

else {
System.out.print("<-");
pis.unread(caracter);

30.
31.
32.

}
} else {
System.out.print((char) caracter);

33.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 85


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

34.
35.
36.

Gua del Estudiante

}
} catch (IOException e) {
System.out.println(e);

37.
}
38.
}/* Metodo main termina aqui */
39. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
La salida de este programa es la siguiente:
if (marca.eq.75)
resultado<-distincion;
Fin del Ejemplo 1.9
En el programa anterior, se le asigna el string "if (marca==75)\n" +
"resultado=distincion;\n", a texto (lnea 10). Este string se lee byte-por-byte
usando PushbackInputStream y se imprime en la salida estndar. Si dos = son
ledos subsecuentemente, entonces se imprime .eq. en la salida estndar. Si un solo
= es ledo, entonces se imprime <- en la salida estndar y el carcter siguiente(d) se
coloca de nuevo en el flujo.
La prxima subclase de InputStream, que se estudia es la clase PipedInputStream.

4.8 La Clase PipedInputStream


Esta clase se usa tpicamente para transferencia de datos entre dos hilos en un
escenario multihilos. Esta clase trabaja en sincronizacin con PipedOutputStream.
Ambas implementan los componentes de entrada y salida de una tubera. Las tuberas
se utilizan para canalizar la salida de un programa (o thread) a la entrada de otro
programa (o thread).
Si se intenta usar ambas clases en el mismo hilo, entonces el hilo puede bloquearse. El
buffer presente en PipedInputStream se usa para separar las operaciones de
lectura de las operaciones de escritura dentro de sus lmites.
La clase PipedInputStream extiende de la clase InputStream.

4.9 La Clase SequenceInputStream


Podra haber una situacin cuando la salida de ms de un flujo necesita ser
concatenada para generar una nica salida. La clase SequenceInputStream se usa
para esto. La clase SequenceInputStream comienza leyendo en grupos flujos de
entrada, y lee desde el primer flujo de entrada hasta alcanzar el fin de archivo, luego
toma el siguiente flujo de entrada y as sucesivamente, hasta que alcanza el fin de
archivo del ltimo flujo de entrada.
Unidad 1: Archivos y Flujos

Libro 2: Core Java 86

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

La clase SequenceInputStream extiende a la clase InputStream.


Ejemplo 1.10
El programa muestra como se puede usar SequenceInputStream.
El cdigo Java comienza aqu
1. import java.io.FileInputStream;
2. import java.io.FileNotFoundException;
3. import java.io.IOException;
4. import java.io.InputStream;
5. import java.io.SequenceInputStream;
6. import java.util.Enumeration;
7. import java.util.NoSuchElementException;
8.
9. /*Definicion de la clase Archivo comienza aqui*/
10. class Archivo implements Enumeration {
11.
private String[] listaArchivos;
12.
13.
14.

private int actual = 0;

15.
16.
17.

public Archivo(String[] listaArchivos) {


this.listaArchivos = listaArchivos;
}/* Constructor Archivo termina aqui */

18.
19.
20.

/* Metodo hasMoreElements comienza aqui */


public boolean hasMoreElements() {

21.
22.
23.

/* Constructor Archivo comienza aqui */

if (actual < listaArchivos.length)


return true;
else

24.
25.
26.

return false;
}/* Metodo hasMoreElements termina aqui */

27.
28.
29.

/* Metodo nextElement comienza aqui */


public Object nextElement() {
InputStream in = null;

30.
31.

if (!hasMoreElements())

Libro 2: Core Java

Unidad 1: Archivos y Flujos 87


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

32.
33.
34.

Gua del Estudiante

throw new NoSuchElementException(


"No mas archivos");
else {

35.
36.
37.

String proximoArchivo = listaArchivos[actual++];


try {
in = new FileInputStream(proximoArchivo);

38.
39.
40.

} catch (FileNotFoundException e) {
System.err.println(
"No se puede abrir el archivo: " +

41.
42.
43.
44.
45.

proximoArchivo);
System.exit(0);
}
}

46.
return in;
47.
} /* Metodo nextElement termina aqui */
48. }/* Definicion de la clase Archivo termina aqui */
49.
50. /* Definicion de la clase comienza aqui */
51. public class SequenceInputStreamEjemplo {
52.
53.
54.
55.
56.
57.

/* Metodo main comienza aqui */


public static void main(String[] args) {
/* Se debe ingresar dos argumentos
por linea de comandos */
if (args.length != 2) {
System.err.println(

58.
59.
60.
61.
62.
63.

"Uso: java SequenceInputStreamEjemplo" +


"archivo1 archivo2");
System.exit(0);
}
try {

64.
65.

Archivo archivo = new Archivo(args);

66.
67.
68.

/* Crear una instancia de SequenceInputStream */


SequenceInputStream s;
s = new SequenceInputStream(archivo);

Unidad 1: Archivos y Flujos

Libro 2: Core Java 88

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

69.
70.
71.

Core Java

int c;
while ((c = s.read()) != -1)

72.
73.
74.

System.out.print((char) c);
/* Cerrar SequenceInputStream */

75.
76.
77.

s.close();
} catch (IOException e) {
e.printStackTrace();

78.
79.

}
}/* Metodo main termina aqui */

80. }/* Definicion de la clase termina aqui */


El cdigo Java termina aqu
La salida del programa ser la siguiente:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entradaGeorge
24
25000.0
true
Fin del Ejemplo 1.10
El programa anterior usa SequenceInputStream para implementar un utilitario de
concatenacin que enlaza archivos en forma secuencial en el orden en que son listados
en la lnea de comandos.
Asuma que se quiere concatenar los archivos miArchivo.txt y Empleado.txt.
Se introducira el siguiente comando en la lnea de comandos:
java SequenceInputStreamEjemplo miArchivo.txt Empleado.txt
Donde,
SequenceInputStreamEjemplo es el nombre del archivo Java.
miArchivo.txt es el primer archivo.
Empleado.txt es el segundo archivo.

Los archivos listados como argumentos para lnea de comandos son miArchivo.txt
y Empleado.txt.
Libro 2: Core Java

Unidad 1: Archivos y Flujos 89


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

miArchivo.txt tiene el siguiente contenido:


El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada Empleado.txt tiene el siguiente contenido:
George
24
25000.0
true
A continuacin se explica la clase StringBufferInputStream.

4.10

La Clase StringBufferInputStream

Una aplicacin puede crear este flujo de un string y leer los contenidos en la forma de
bytes. Esta clase slo usa los ocho bits bajos usados para representar un carcter. La
clase StringBufferInputStream extiende de Inputstream. Esta clase est
actualmente desaprobada (deprecated) y por esto no es recomendable usarla.
Ahora, se discute en detalle la clase OutputStream.

5. La Clase OutputStream
La clase OutputStream es una clase abstracta que permite escribir datos en la forma
de bytes (8-bits). Las clases que son subclases de OutputStream deben implementar
un mtodo que retorne al menos un byte de datos como salida. Sin embargo, las
subclases pueden sobrescribir los mtodos proporcionados por OutputStream para
tener mayor eficiencia o para aadir algunas caractersticas.
La clase OutputStream extiende de la clase Object. Las subclases de la clase
OutputStream se muestran en la Figura 1.5.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 90

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Figura 1.5: La Clase OutputStream y sus Subclases

La clase ObjectOutputStream, que es una subclase de la clase OutputStream, es


un flujo de byte que se usa para serializar objetos durante la serializacin de objetos. Se
estudiarn las otras subclases de OutputStream en esta unidad. Se comienza con la
clase ByteArrayOutputStream.

5.1 La Clase ByteArrayOutputStream


La clase ByteArrayOutputStream se usa como un OutputStream para escribir
datos en un arreglo de byte. Esta clase mantiene internamente un buffer que almacena
los bytes que sern escritos en el arreglo de byte.
La clase ByteArrayOutputStream extiende OutputStream. Observe el Ejemplo
1.11.
Ejemplo 1.11
Este ejemplo ilustra como trabajar con la clase ByteArrayOutputStream.
El cdigo Java comienza aqu
1.

import java.io.BufferedReader;

2. import java.io.ByteArrayOutputStream;
3. import java.io.IOException;
4. import java.io.InputStreamReader;
5.
6. /* Definicion de la clase comienza aqui */

Libro 2: Core Java

Unidad 1: Archivos y Flujos 91


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

7. public class ByteArrayOutputStreamEjemplo {


8.
/* Metodo main comienza aqui */
9.
public static void main(String[] args) {
10.
11.
12.
13.
14.
15.
16.
17.

try {
String texto;
/* Crear instancia de BufferedReader */
BufferedReader br;
br = new BufferedReader(
new InputStreamReader(System.in)
);

18.
19.
20.

do {
System.out.println("Ingrese texto:");
texto = br.readLine();

21.
22.
23.

texto = texto.trim();
} while (texto.length() == 0);

24.
25.
26.

/* Declaracion de arreglo de byte */


byte arregloBytes1[] = texto.getBytes();

27.
28.
29.

/* Crear una instancia de ByteArrayOutputStream */


ByteArrayOutputStream aros;
aros = new ByteArrayOutputStream();

30.
31.
32.

aros.write(arregloBytes1);
System.out.println(
"Contenido del ByteArrayOutputStream : " +

33.
34.
35.

System.out.println(

36.
37.
38.

"Se copia el ByteArrayOutputStream " +


"a un arreglo de byte: ");
byte arregloBytes2[] = aros.toByteArray();

39.
40.

/* Mostrar valor de arregloBytes2 */

41.
42.
43.

aros.toString());

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


System.out.print((char) arregloBytes2[i]);

Unidad 1: Archivos y Flujos

Libro 2: Core Java 92

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

44.
45.
46.

Core Java

System.out.println();
} catch (IOException e) {
System.out.println(e);

47.
}
48.
}/* Metodo main termina aqui */
49. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
La salida de este programa es la siguiente:
Ingrese texto:
Bienvenido a IBM
Contenido del ByteArrayOutputStream : Bienvenido a IBM
Se copia el ByteArrayOutputStream a un arreglo de byte:
Bienvenido a IBM
Fin del Ejemplo 1.11
El programa anterior toma el string Bienvenido a IBM como entrada del usuario.
Este es convertido en un arreglo de byte. Un ByteArrayOutputStream se abre sobre
este arreglo de byte, y sus contenidos son impresos en la salida estndar usando el
mtodo ByteArrayOutputStream.toString(). Los contenidos de este flujo son
ledos byte-por-byte e impresos en la salida estndar.
A continuacin se explica la clase FileOutputStream.

5.2 La Clase FileOutputStream


FileOutputStream se usa para escribir bytes de datos a un archivo existente en el
sistema de archivos. Un objeto File o FileDescriptor se usa como argumento para
representar el archivo al cual se va a escribir. El comportamiento de la proteccin al
archivo (file locks), mientras se usa esta clase depende del sistema de operacin
subyacente. Esta clase extiende OutputStream. Se presenta el Ejemplo 1.12.
Ejemplo 1.12
Este ejemplo muestra como usar un objeto FileOutputStream.
El cdigo Java comienza aqu
1. import java.io.BufferedReader;
2. import java.io.FileOutputStream;
3. import java.io.InputStreamReader;
4. import java.io.PrintStream;
5.
6. /* Definicion de la clase comienza aqui */
Libro 2: Core Java

Unidad 1: Archivos y Flujos 93


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

7. public class FileOutputStreamEjemplo {


8.
/* Metodo main comienza aqui */
9.
public static void main(String[] args) {
10.
11.
12.

try {
FileOutputStream salida;
PrintStream ps;

13.
14.
15.

String nombreArchivo = "archivoSalida.txt";


String texto;

16.
17.

/* Crear instancia de BufferedReader */


BufferedReader br;

18.
19.
20.

br = new BufferedReader(
new InputStreamReader(System.in)
);

21.
22.
23.

do {
System.out.println("Ingrese texto");

24.
25.
26.

texto = br.readLine();
texto = texto.trim();
} while (texto.length() == 0);

27.
28.
29.

/* Crear un nuevo archivo de flujo de salida */


salida = new FileOutputStream(nombreArchivo);

30.
31.
32.

/* Conectar flujo de impresora


al flujo de salida */

33.
34.
35.

ps = new PrintStream(salida);
ps.println(texto);
System.out.println(

36.
37.
38.
39.
40.
41.
42.
43.

"Texto escrito en el archivo " +


nombreArchivo);
/* Cerrar PrintStream */
ps.close();
} catch (Exception e) {
System.err.println(e);
}

Unidad 1: Archivos y Flujos

Libro 2: Core Java 94

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

44.
}/* Metodo main termina aqui */
45. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
El archivo archivoSalida.txt ser creado si no existe, dependiendo de la
plataforma en la cual se ejecute la JVM, y contendr el siguiente string, si el string de
entrada introducido es Bienvenido a IBM.
Ingrese texto
Bienvenido a IBM
Texto escrito en el archivo archivoSalida.txt
Fin del Ejemplo 1.12
En el ejemplo anterior, el string Bienvenido a IBM se toma como entrada del usuario
y
se
escribe
a
un
archivo
llamado
archivoSalida.txt,
usando
FileOutputStream.
A continuacin se estudia FilterOutputStream y sus subclases.

5.3 La Clase FilterOutputStream


FilterOutputStream, como el nombre lo sugiere, se usa para trabajar en el flujo de
salida, manipulando los datos de salida basados en ciertos filtros (condiciones)
definidas por el usuario.
La clase FilterOutputStream extiende OutputStream. La condicin de filtrado
puede estar basada en varias condiciones, como escribir solo caracteres ASCII o
escribir los caracteres de un rango especfico.

5.4 La Clase BufferedOutputStream


La clase BufferedOutputStream permite a los flujos de salida almacenar en un
buffer los bytes que estn siendo escritos. Los datos que son escritos en otros flujos
usualmente no esta en un buffer, por lo que se tiene que acceder al disco por cada byte
de datos escrito. BufferedOutputStream mantiene un buffer interno como arreglo
donde se escriben los bytes para el flujo. Los datos son guardados en este buffer hasta
que se llena y son escritos en la salida. Los datos que son escritos en el buffer son
escritos en la salida tambin, cuando el buffer es vaciado explcitamente o el flujo es
cerrado.
La clase BufferedOutputStream extiende FilterOutputStream.
A continuacin se presenta un ejemplo que usa la clase BufferedOutputStream.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 95


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Ejemplo 1.13
El programa en este ejemplo imprime los caracteres correspondientes a los valores
enteros del 65 al 90.
El cdigo Java comienza aqu
1.

import java.io.BufferedOutputStream;

2. import java.io.DataOutputStream;
3. import java.io.FileNotFoundException;
4. import java.io.FileOutputStream;
5. import java.io.IOException;
6.
7. /* Definicion de la clase comienza aqui */
8. public class BufferedOutputStreamEjemplo {
9.
/* Metodo main comienza aqui */
10.
public static void main(String[] args) {
11.
12.
13.
14.
15.
16.

try {
/* Debe ingresar dos argumentos en
linea de comandos */
if (args.length != 2) {
System.err.println(
"Debe ingresar algo asi:");

17.
18.

System.err.println(
"java BufferedOutputStreamEjemplo " +

19.
20.
21.

"nombreArchivo cantidadBuffer");
System.exit(1);
}

22.
23.
24.

/* Convertir el argumento de la cantidad


del buffered de la linea de

25.
26.
27.

commando a entero */
int cantidadBuffer = Integer.parseInt(args[1]);

28.
29.
30.

/* Crear una instancia de FileOutputStream */


FileOutputStream fos = new FileOutputStream(args[0]);

31.
32.

/* Crear una instancia de BufferedOutputStream */


BufferedOutputStream bos;

Unidad 1: Archivos y Flujos

Libro 2: Core Java 96

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

33.
34.
35.

bos = new BufferedOutputStream(fos, cantidadBuffer);

36.
37.
38.

DataOutputStream dos = new DataOutputStream(bos);


for (int i = 65; i < 91; ++i) {
dos.writeInt(i);

/* Crear una instancia de DataOutputStream */

39.
40.
41.

System.out.print((char) i + " ");


}

42.
43.

System.out.println();
dos.close();

44.
45.
46.

} catch (FileNotFoundException e) {
System.out.println(
"Archivo no encontrado");

47.
48.
49.

System.exit(0);
} catch (IllegalArgumentException e) {
System.out.println(

50.
51.
52.
53.
54.
55.
56.
57.
58.

"La cantidad del buffer no " +


"debe ser cero ni negativo");
System.exit(0);
} catch (IOException e) {
System.out.println(
"Error de Entrada/Salida");
System.exit(0);
}
}/* Metodo main termina aqui */

59. }/* Definicion de la clase termina aqui */


El cdigo Java termina aqu
La salida que se obtiene es la siguiente, y ser escrita en el argumento especificado en
la lnea de comandos BufferSalida.txt:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Fin del Ejemplo 1.13
El programa se corre como sigue:
java BufferedOutputStreamEjemplo BufferSalida.txt 100
Donde,
Libro 2: Core Java

Unidad 1: Archivos y Flujos 97


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

BufferedOutputStreamEjemplo es el nombre del archivo Java.


BufferSalida.txt es el archivo
correspondientes a los valores enteros.

que

almacena

los

caracteres

100 es el tamao del buffer.

5.5 La Clase DataOutputStream


Los tipos de datos primitivos usualmente tienen una representacin que es dependiente
de la mquina. La clase DataOutputStream permite que una aplicacin escriba los
tipos de datos primitivos de una forma independiente de la mquina.
La clase DataOutputStream extiende de FilterOutputStream. Los datos escritos
por este flujo pueden ser recuperados al programa Java por DataInputStream.

5.6 La Clase PrintStream


Se podra querer escribir datos en la misma representacin de tipos de datos que utiliza
la plataforma subyacente. La clase PrintStream permite hacer esto. La codificacin
por defecto de los caracteres de la plataforma se usa para convertir los caracteres
escritos usando PrintStream a bytes. Es ms til cuando se van a escribir
caracteres, en vez de bytes.
La clase PrintStream extiende de la clase FilterOutputStream.
El ejemplo a continuacin muestra el uso de la clase PrintStream.
Ejemplo 1.14
El cdigo Java comienza aqu
1.
2.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;

3.
4.
5.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

6.
7.
8.

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

9. import java.io.PrintStream;
10.
11. /* Definicion de la clase PrintStreamEjemplo comienza aqui */
12. public class PrintStreamEjemplo {
13.
/* Metodo main comienza aqui */

Unidad 1: Archivos y Flujos

Libro 2: Core Java 98

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

14.
15.
16.

Core Java

public static void main(String[] args) {


try {
String archivoOrigen = "miArchivo.txt";

17.
18.
19.

String archivoDestino = "miArchivoDestino.txt";


String texto;

20.
21.
22.

/* Crear una instancia de BufferedInputStream */


BufferedInputStream bis;
bis = new BufferedInputStream(

23.
24.

new FileInputStream(archivoOrigen)
);

25.
26.
27.

/* Crear una instancia de PrintStream */


PrintStream ps;

28.
29.
30.

ps = new PrintStream(
new BufferedOutputStream(
new FileOutputStream(archivoDestino)

31.
32.
33.

)
);

34.
35.
36.

/* Establecer la entrada, salida y error estandar */


System.setIn(bis);
System.setOut(ps);

37.
38.
39.

System.setErr(ps);

40.
41.
42.

BufferedReader br;
br = new BufferedReader(
new InputStreamReader(System.in)

/* Crear una instancia de BufferedReader */

43.
44.
45.

/* Leer de BufferedReader */

46.
47.

while ((texto = br.readLine()) != null)


System.out.println(texto);

48.
49.
50.

System.out.println(
"Salida escrita en este archivo");

Libro 2: Core Java

);

Unidad 1: Archivos y Flujos 99


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

51.
52.
53.

/* Cerrar el PrintStream */
ps.close();

54.
55.
56.

} catch (FileNotFoundException e) {
System.out.println("Archivo no encontrado");
System.exit(0);

57.
58.
59.

} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);

60.
61.

}
}/* Metodo main termina aqui */

62. }/* Definicion de la clase PrintStreamEjemplo termina aqui */


El cdigo Java termina aqu
Este programa redirige la salida a un archivo llamado miArchivoDestino.txt.
Los contenidos de miArchivo.txt son los siguientes:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Los contenidos de miArchivoDestino.txt son los siguientes:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Salida escrita en este archivo
Fin del Ejemplo 1.14
En el programa anterior, los contenidos de miArchivo.txt son ledos usando
BufferedInputStream.
Los
contenidos
son
escritos
en
el
archivo
miArchivoDestino.txt usando PrintStream.

5.7 La Clase PipedOutputStream


La clase PipedOutputStream es una subclase de OutputStream. Usualmente,
trabaja en combinacin con PipedInputStream para crear un canal (pipe) de
comunicacin.
Se contina el anlisis con la clase Reader y sus subclases.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 100

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

6. La Clase Reader
Se han visto hasta ahora formas de leer y escribir datos como bytes. Los flujos tambin
se usan para ello. Se puede querer realizar estas operaciones sobre datos de tipo
caracter en vez de bytes. En estos casos, se usan las clases Reader y Writer.
Reader es una superclase abstracta para los flujos de caracteres que se usan para la
lectura de caracteres. La clase abstracta Reader provee el API junto con la
implementacin parcial para todos los flujos de lectura que se usan para leer caracteres
de 16-bit. Los lectores estn adecuados para manejar caracteres unicode y por esto son
preferibles a utilizar un flujo de entrada de objeto.
La clase Reader extiende de la clase Object. La Figura 1.6 muestra la clase Reader
y sus subclases.

Figura 1.6: La Clase Reader y sus Subclases

A continuacin se estudiarn las subclases de la clase Reader comenzando con la


clase BufferedReader.

6.1 La Clase BufferedReader


La clase BufferedReader es un tipo de lector, como los flujos tipo buffer, mantiene un
buffer interno de caracteres, y por esto permite leer caracteres, lneas, arreglos y strings
de una forma eficiente.
El tamao del buffer puede ser especificado, cuando no se especifica, se usa el tamao
por defecto.
La clase BufferedReader extiende a la clase Reader.
Libro 2: Core Java

Unidad 1: Archivos y Flujos 101


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Considere el Ejemplo 1.15, que muestra el uso de la clase BufferedReader.


Ejemplo 1.15
El cdigo Java comienza aqu
1. import java.io.BufferedReader;
2. import java.io.FileNotFoundException;
3. import java.io.FileReader;
4. import java.io.IOException;
5.
6. /*Definicion de la clase BufferedReaderEjemplo comienza aqui*/
7. public class BufferedReaderEjemplo {
8.
/* Metodo main comienza aqui */
9.
public static void main(String[] args) {
10.
11.
12.

try {
/* Declaracion de variables */
String dato;

13.
14.

/* Crear instancia de FileReader */

15.
16.
17.

FileReader fReader = new FileReader("miArchivo.txt");

18.
19.
20.

BufferedReader bReader = new BufferedReader(fReader);

21.
22.
23.

while ((dato = bReader.readLine()) != null)


System.out.println(dato);

24.
25.
26.

/* Cerrar BufferedReader y FileReader */


bReader.close();
fReader.close();

/* Crear instancia de BufferedReader */

/* Leer hasta alcanzar fin de archivo */

27.
28.
29.

} catch (FileNotFoundException e) {
System.out.println("Archivo no encontrado");
System.exit(0);

30.
31.
32.

} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);

33.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 102

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

34.
}/* Metodo main termina aqui */
35. }/*Definicion de la clase BufferedReaderEjemplo termina aqui*/
El cdigo Java termina aqu
El archivo de entrada miArchivo.txt contiene el siguiente texto:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
La salida del programa ser la siguiente:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Fin del Ejemplo 1.15
El programa del Ejemplo 1.15 lee el contenido del archivo miArchivo.txt a travs de
BufferedReader y lo muestra en la salida estndar.
A continuacin se explica la clase LineNumberReader, que ayuda a saber el nmero
de lneas dentro de un archivo.

6.2 La Clase LineNumberReader


La clase LineNumberReader se puede usar en el caso de que se necesite estar al
tanto del nmero de la lnea actual de los datos ledos. El nmero de lnea actual es
incrementado cada vez que se lee el carcter de fin de lnea (retorno de carro '\r',
nueva lnea '\n', o retorno de carro \r seguido inmediatamente de nueva lnea \n).
La clase LineNumberReader extiende BufferedReader.
Considere el Ejemplo 1.16, que muestra su uso.
Ejemplo 1.16
El programa busca en el archivo de texto especificado, pasado como argumento
args[1] por la lnea de comandos, un patrn que se pasa en el argumento args[0]
de la lnea de comandos y muestra cada lnea que tiene el patrn con su nmero de
lnea.
El cdigo Java comienza aqu
1.

import java.io.FileNotFoundException;

2. import java.io.FileReader;
3. import java.io.IOException;
Libro 2: Core Java

Unidad 1: Archivos y Flujos 103


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

4. import java.io.LineNumberReader;
5.
6. /*Definicion de la clase comienza aqui*/
7. public class LineNumberReaderEjemplo {
8.
/* Metodo main comienza aqui */
9.
public static void main(String[] args) {
10.
11.
12.

/* Debe ingresar 2 argumentos en la linea de comandos */


if (args.length != 2) {
System.err.println(

13.
14.

"Debe ingresar algo asi:");


System.err.println(

15.
16.
17.

"java LineNumberReaderEjemplo " +


"palabraABuscar nombreArchivo");
System.exit(1);

18.
19.
20.

21.
22.
23.

String palabraABuscar = args[0];


/* args[1] tiene el nombre del archivo de busqueda */
String nombreArchivo = args[1];

24.
25.
26.

boolean encontrada = false;


String texto;

27.
28.
29.

try {
/* Crear instancia de fileReader */
FileReader fReader = new FileReader(nombreArchivo);

30.
31.
32.

/* args[0] tiene la palabra a buscar */

/* Crear instancia de LineNumberReader */


LineNumberReader lnReader;

33.
34.
35.

lnReader = new LineNumberReader(fReader);

36.
37.

while ((texto = lnReader.readLine()) != null) {


/* Si se encuentra la palabra buscada */

38.
39.
40.

if (texto.indexOf(palabraABuscar) != -1) {
/* Extraer el numero de linea donde
la busqueda encontro la palabra */

/* Leer linea por linea del archivo */

Unidad 1: Archivos y Flujos

Libro 2: Core Java 104

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

41.
42.
43.

int numeroLinea = lnReader.getLineNumber();


System.out.println(
nombreArchivo +

44.
45.
46.

"[" +
numeroLinea +
"]: " +

47.
48.
49.

texto);
/* Establecer la bandera */

50.
51.

encontrada = true;
}

52.
53.
54.

55.
56.
57.

if (!encontrada)
System.out.println(
"La palabra " +

/* Cuando no se encuentra la palabra en el archivo */

58.
59.
60.

palabraABuscar +
" no fue encontrada en " +
nombreArchivo);

61.
62.
63.

/* Cerrar el LineNumberReader */
lnReader.close();

64.
65.
66.

} catch (FileNotFoundException e) {
System.err.println(
"Archivo " +

67.
68.
69.
70.
71.
72.
73.
74.

nombreArchivo +
" no encontrado");
System.exit(0);
} catch (IOException e) {
System.out.println(
"Error de Entrada/Salida");
System.exit(0);
}

75.
}/* Metodo main termina aqui */
76. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
Libro 2: Core Java

Unidad 1: Archivos y Flujos 105


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

La salida del programa ser la siguiente:


miArchivo.txt[1]: El BufferedReader es un tipo de Reader(lector).
miArchivo.txt[2]: Se utiliza para leer los caracteres o Strings
miArchivo.txt[3]: desde el flujo de entrada
Fin del Ejemplo 1.16
El archivo de entrada miArchivo.txt contiene el siguiente texto:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Asuma que se quiere buscar la palabra es en miArchivo.txt.
Se introduce el siguiente comando:
java LineNumberReaderEjemplo es miArchivo.txt
Aqu,
LineNumberReaderEjemplo es el nombre del archivo Java.
es es la palabra a buscar.
miArchivo.txt en el archivo en el cual se va a buscar la palabra.
A continuacin se estudia la clase CharArrayReader, que permite leer de un arreglo
de caracteres.

6.3 La Clase CharArrayReader


La clase CharArrayReader se usa para leer caracteres de un arreglo de caracteres.
La clase CharArrayReader extiende Reader.
Considere el Ejemplo 1.17, que muestra su uso.
Ejemplo 1.17
El programa lee tres entradas del usuario. La primera es una cadena, que se copia al
objeto CharArrayReader. La segunda y tercera son enteros que indican el ndice de
inicio y el nmero de caracteres a copiar del objeto CharArrayReader existente a un
nuevo objeto CharArrayReader.
El cdigo Java comienza aqu
1. import java.io.BufferedReader;
2. import java.io.CharArrayReader;
3. import java.io.IOException;
Unidad 1: Archivos y Flujos

Libro 2: Core Java 106

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

4. import java.io.InputStreamReader;
5.
6. /*Definicion de la clase comienza aqui*/
7. public class CharArrayReaderEjemplo {
8.
/* Metodo main comienza aqui */
9.
public static void main(String[] args) {
10.
11.
12.

try {
/* Crear una instancia de BufferedReader */
BufferedReader br;

13.
14.

br = new BufferedReader(
new InputStreamReader(System.in)

15.
16.
17.

);
/* Declaracion de variable */

18.
19.
20.

String texto;
int longitudTexto;
do {

21.
22.
23.

/* Obtener una linea de texto del usuario */


System.out.println("Ingrese una linea de texto");
texto = br.readLine();

24.
25.
26.

texto = texto.trim();

27.
28.
29.

longitudTexto = texto.length();
System.out.println(
"La longitud del texto es: " +

/* Obtener la longitud del texto ingresado */

30.
31.
32.

longitudTexto);
} while (longitudTexto == 0);

33.
34.
35.

char arregloChar[] = new char[longitudTexto];

36.
37.

desde la posicion 0 en arregloChar */


texto.getChars(0, longitudTexto, arregloChar, 0);

38.
39.
40.

CharArrayReader caReader1;
caReader1 = new CharArrayReader(arregloChar);

Libro 2: Core Java

/* El metodo getChars copia lo que hay en texto

Unidad 1: Archivos y Flujos 107


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

41.
42.
43.

int i;

44.
45.
46.

while ((i = caReader1.read()) != -1)


System.out.print((char) i);

47.
48.
49.

int inicio, numCaracteres;

50.
51.

System.out.println("Contenido de caReader1: ");

do {
System.out.println(
"\nIngrese el indice del " +

52.
53.
54.

"caracter desde donde quiere copiar");


inicio = Integer.parseInt(br.readLine());

55.
56.
57.

if (inicio < 0)
System.out.println(
"El indice no puede ser negativo");

58.
59.
60.

if (inicio > longitudTexto - 1)


System.out.println(
"El indice no puede ser mayor " +

61.
62.
63.

"que la longitud de la cadena");


} while (inicio < 0 || inicio > longitudTexto - 1);

64.
65.
66.

do {
System.out.println(
"\nIngrese el numero de " +

67.
68.
69.

"caracteres que quiere copiar");


numCaracteres = Integer.parseInt(br.readLine());

70.
71.
72.

if (numCaracteres < 0)
System.out.println(
"El numero de caracteres " +

73.
74.

"no puede ser negativo");


if (numCaracteres > longitudTexto)

75.
76.
77.

System.out.println(
"El numero de caracteres no puede " +
"ser mayor que la longitud de la cadena");

Unidad 1: Archivos y Flujos

Libro 2: Core Java 108

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

78.
79.
80.

} while ((numCaracteres < 0) ||


(numCaracteres > longitudTexto));

81.
82.
83.

CharArrayReader caReader2;
caReader2 = new CharArrayReader(
arregloChar,

84.
85.
86.

inicio,
numCaracteres
);

87.
88.

System.out.println("Contenido de caReader2: ");

89.
90.
91.

while ((i = caReader2.read()) != -1) {


System.out.print((char) i);
}

92.
93.
94.

} catch (NumberFormatException e) {
System.out.println("Valor ingresado invalido");
System.exit(0);

95.
96.
97.

} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);

98.
}
99.
}/* Metodo main termina aqui */
100. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
La salida de este cdigo con las entradas de prueba ser la siguiente:
Ingrese una linea de texto
Bienvenido a IBM
La longitud del texto es: 16
Contenido de caReader1:
Bienvenido a IBM
Ingrese el indice del caracter desde donde quiere copiar
13
Ingrese el numero de caracteres que quiere copiar
3
Contenido de caReader2:
IBM
Fin del Ejemplo 1.17

Libro 2: Core Java

Unidad 1: Archivos y Flujos 109


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Los pasos seguidos en el programa anterior son los siguientes:

Al usuario, primero, se le pide una lnea de texto. La lnea del usuario es:

Bienvenido a IBM La longitud de esta lnea se calcula e imprime (que es 16).

Luego se copia en CharArrayReader caReader1.

Despus, se toma el conjunto de caracteres a copiar. Se toma el ndice de inicio


y el nmero de caracteres a copiar.

Finalmente, se copian los caracteres en otro CharArrayReader caReader2 y


se muestran en la salida estndar.

6.4 La Clase FilterReader


FilterReader, como el nombre lo sugiere, se usa para trabajar en el flujo de
caracteres manipulando los datos de entrada basado en ciertos filtros (condiciones)
definidas por el usuario. La clase abstracta FilterReader extiende de Reader.

6.5 La Clase PushbackReader


La clase PushbackReader es similar a la clase PushbackInputStream. Los
caracteres que son ledos por el Reader pueden ser colocados nuevamente en el flujo.
Esta clase extiende FilterReader.
Considere el Ejemplo 1.18 que muestra su uso
Ejemplo 1.18
Este programa lee caracteres usando PushbackReader, que se abre sobre un
CharArrayReader, que es, a su vez, abierto sobre un arreglo de caracteres. El arreglo
de caracteres tiene tres caracteres I, B, y M.
El cdigo Java comienza aqu...
1. import java.io.CharArrayReader;
2. import java.io.PushbackReader;
3.
4. /*Definicion de la clase PushbackReaderEjemplo comienza aqui*/
5. public class PushbackReaderEjemplo {
6.
/* Metodo main comienza aqui */
7.
8.
9.
10.
11.

public static void main(String[] args)


throws Exception{
char buffer[] = {'I', 'B', 'M'};
char letra;

Unidad 1: Archivos y Flujos

Libro 2: Core Java 110

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

12.
13.
14.

/* Establecer lector para leer


del arreglo de caracteres */

15.
16.
17.

CharArrayReader car;
car = new CharArrayReader(buffer);
PushbackReader pr;

18.
19.
20.

pr = new PushbackReader(car, 1);


/* Leer un caracter */
letra = (char) pr.read();

21.
22.

System.out.println(letra);

23.
24.
25.

/* Leer otro caracter */


letra = (char) pr.read();
System.out.println(letra);

26.
27.
28.

/* "Desleer" un caracter */
pr.unread(letra);

29.
30.
31.

/* Leerlo otra vez */


letra = (char) pr.read();

32.
System.out.println(letra);
33.
}/* Metodo main termina aqui */
34. }/*Definicion de la clase PushbackReaderEjemplo termina aqui*/
El cdigo Java termina aqu
La salida del programa anterior es la siguiente:
I
B
B
Fin del Ejemplo 1.18
Este programa lee caracteres usando PushbackReader, que se abre sobre un
CharArrayReader, abierto sobre un arreglo de caracteres. El arreglo de caracteres
tiene tres caracteres I, B y M. PushbackReader lee el primer carcter I y lo
muestra en la salida estndar, luego, lee el prximo carcter B y los muestra en la
salida estndar. Posteriormente, des-lee el segundo carcter. Ahora
PushbackReader lee el prximo caracter, que es B en vez de M. Finalmente el
carcter ledo, B, se imprime en la salida estndar.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 111


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

A continuacin se explica la clase InputStreamReader.

6.6 La Clase InputStreamReader


Se ha aprendido acerca de flujos de byte y flujos de carcter. En algunos casos, se
podra necesitar usar los flujos de byte y convertirlos en caracteres antes de que
puedan ser usados. InputStreamReader realiza esta operacin de acuerdo con el
esquema de codificacin de caracteres especificado.
Esto se muestra en la Figura 1.7.

Figura 1.7: InputStreamReader como Puente entre Flujos de Byte y Flujos de Caracter

La clase InputStreamReader extiende de la clase Reader. Se puede usar


InputStreamReader para tomar la entrada del usuario del dispositivo de entrada
estndar (teclado). La entrada del usuario en el dispositivo de entrada estndar se
captura primero abriendo un InputStream en System.in. InputStream, lee datos
en la forma de bytes. Este es encapsulado, usando el InputStreamReader, que
convierte los datos en forma de byte en caracter. BufferedReader envuelve a
InputStreamReader, y finalmente se convierte la entrada del usuario en caracteres.
Esto se muestra en la Figura 1.8.

Figura 1.8: InputStreamReader como Puente entre InputStream y BufferedReader

Unidad 1: Archivos y Flujos

Libro 2: Core Java 112

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

La entrada del usuario tomada del teclado se lee usando InputStreamReader y luego
es convertida en caracteres. El contenido de un archivo en un disco (disco duro o disco
flexible) puede ser ledo carcter por carcter usando FileReader.
Los datos ledos pueden ser transferidos a otras computadoras conectadas a la red a
travs de conexiones de conectores (socket). Los datos pueden ser mostrados como
caracteres en la salida estndar (monitor) en la misma computadora o mostrados en la
salida estndar de una computadora diferente en la red usando PrintStream.
Esto se ilustra en la Figura 1.9.

Figura 1.9: Lectura y Escritura de Datos a travs de Flujos de Caracter

Si el esquema de codificacin de caracteres usado no se especifica explcitamente, el


esquema de codificacin de caracteres por defecto para la plataforma ser usado. Es
recomendable envolver un InputStreamReader dentro de un BufferedReader,
como se muestra en el siguiente cdigo, para mejorar la eficiencia.
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
Considere el Ejemplo 1.19, que ilustra el uso de InputStreamReader.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 113


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Ejemplo 1.19
En este programa, se le pide al usuario que introduzca una lnea de texto. La lnea del
usuario es 'Bienvenido a IBM'. Este texto se lee y se muestra en la salida estndar.
El cdigo Java comienza aqu
1.

import java.io.BufferedReader;

2. import java.io.IOException;
3. import java.io.InputStreamReader;
4.
5. /*Definicion de la clase comienza aqui*/
6. public class InputStreamReaderEjemplo {
7.
8.
9.
10.
11.
12.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {
/* Crear instancia de BufferedReader */
BufferedReader br;
br = new BufferedReader(

13.
14.
15.

new InputStreamReader(System.in)
);

16.
17.
18.

/* Indicar al usuario de ingresar


una linea de texto */
System.out.println("Ingrese texto");

19.
20.
21.

/* Leer el texto */
String texto = br.readLine();

22.
23.
24.

/* Mostrar el texto ingresado */


System.out.println(

25.
26.
27.
28.
29.

"El texto ingresado fue: " +


texto);
} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);

30.
}
31.
}/* Metodo main termina aqui */
32. }/* Definicion de la clase termina aqui */
Unidad 1: Archivos y Flujos

Libro 2: Core Java 114

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

El cdigo Java termina aqu


La salida de este programa es:
Ingrese texto
Bienvenido a IBM
El texto ingresado fue: Bienvenido a IBM
Fin del Ejemplo 1.19
A continuacin se estudiar la clase FileReader, usada para leer caracteres de
archivos.

6.7 La Clase FileReader


FileReader es una clase que permite leer datos caracteres de un archivo. Esta clase
extiende a la clase InputStreamReader.
Considere el Ejemplo 1.20, que muestra su uso.
Ejemplo 1.20
El cdigo Java comienza aqu
1. import java.io.File;
2. import java.io.FileNotFoundException;
3. import java.io.FileReader;
4. import java.io.FileWriter;
5. import java.io.IOException;
6.
7. /*Definicion de la clase FileReaderEjemplo comienza aqui*/
8. public class FileReaderEjemplo {
9.
/* Metodo main comienza aqui */
10.
public static void main(String[] args) {
11.
12.
13.

/* Debe ingresar dos argumentos en linea de comandos */


try {
if (args.length != 2) {

14.
15.
16.

System.err.println(
"Debe ingresar algo asi:");
System.err.println(

17.
18.
19.

"java FileReaderEjemplo " +


"archivoOrigen archivoDestino");
System.exit(1);

20.
Libro 2: Core Java

}
Unidad 1: Archivos y Flujos 115
Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

21.
22.
23.

/* args[0] tiene el nombre del archivo fuente */


String nombreArchivoOrigen = args[0];

24.
25.
26.

/* args[1] tiene el nombre del archivo destino */


String nombreArchivoDestino = args[1];

27.
28.
29.

/* Crear instancia de File */


File archivoEntrada = new File(nombreArchivoOrigen);

30.
31.

File archivoSalida

32.
33.
34.

/* Crear instancia de FileReader */


FileReader entrada = new FileReader(archivoEntrada);

35.
36.
37.

/* Crear instancia de FileWriter */


FileWriter salida = new FileWriter(archivoSalida);
int c;

38.
39.
40.

System.out.println(
"Contenido de " +

41.
42.
43.

= new File(nombreArchivoDestino);

nombreArchivoOrigen +
"\n");

44.
45.
46.

while ((c = entrada.read()) != -1) {


System.out.print((char) c);
salida.write(c);

47.
48.
49.

50.
51.
52.

System.out.println("\n\n");
/* Cerrar todos los archivos abiertos */
entrada.close();

53.
54.

salida.close();

55.
56.
57.

/* Ahora mostrar el contenido del archivo destino */


FileReader reader;
reader = new FileReader(

Unidad 1: Archivos y Flujos

Libro 2: Core Java 116

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

58.
59.
60.

new File(nombreArchivoDestino)
);

61.
62.
63.

System.out.println(
"Contenido de " +
nombreArchivoDestino +

64.
65.
66.

/* Leer del from destination file */

67.
68.

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


System.out.print((char) c);

69.
70.
71.

System.out.println();
entrada.close();

72.
73.
74.

"\n");

} catch (FileNotFoundException e) {
System.out.println(
"Archivo fuente " +

75.
76.
77.
78.
79.
80.
81.
82.
83.

args[0] +
" no encontrado");
System.exit(0);
} catch (IOException e) {
System.out.println(
"Error de Entrada/Salida");
System.exit(0);
}
}/* Metodo main termina aqui */

84. }/*Definicion de la clase FileReaderEjemplo termina aqui*/


El cdigo Java termina aqu
Asuma que se quiere copiar los contenidos de miArchivo.txt a tuArchivo.txt.
Se introduce el siguiente comando en la lnea de comandos:
java FileReaderEjemplo miArchivo.txt tuArchivo.txt
Aqu,
FileReaderEjemplo es el archivo del programa Java.
miArchivo.txt es el nombre del archivo fuente.
tuArchivo.txt es el nombre del archivo destino.
Libro 2: Core Java

Unidad 1: Archivos y Flujos 117


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

La salida del cdigo anterior ser la siguiente:


Contenido de miArchivo.txt
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada

Contenido de tuArchivo.txt
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Fin del Ejemplo 1.20
El programa del Ejemplo 1.20 es muy simple. Abre un FileReader en
miArchivo.txt, y un FileWriter en tuArchivo.txt. El archivo de entrada
miArchivo.txt tiene el siguiente texto:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Despus de copiar en el archivo de salida, tuArchivo.txt tiene el siguiente texto:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada

6.8 La Clase PipedReader


La clase PipedReader es una subclase de Reader, se usa para utilizar una tubera
de caracteres en flujos de entrada. Utilizar una tubera en un flujo de entrada de
caracteres implica abrir un flujo de caracteres de entrada en el tope de otro. Vase la
explicacin de PipedInputStream.
Esta clase extiende a la clase Reader.

6.9 La Clase StringReader


Esta clase se usa para leer caracteres de un string. Esta clase tambin extiende a la
clase Reader.
Considere el Ejemplo 1.21, que muestra su uso:

Unidad 1: Archivos y Flujos

Libro 2: Core Java 118

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Ejemplo 1.21
El cdigo Java comienza aqu
1. /*Definicion de la clase StringReaderEjemplo comienza aqui*/
2. public class StringReaderEjemplo {
3.
/* Metodo main comienza aqui */
4.
5.
6.

public static void main(String[] args) {


try {
String texto = "Bienvenido a IBM";

7.
8.
9.

StringReader sReader = new StringReader(texto);


int i;

10.
11.
12.

/* Leer de StringReader */
while ((i = sReader.read()) != -1)
System.out.print((char) i);

13.
14.
15.
16.
17.

} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);
}
}/* Metodo main termina aqui */

18. }/* Definicion de la clase StringReaderEjemplo termina aqui */


El cdigo Java termina aqu
La salida del programa anterior es la siguiente:
Bienvenido a IBM
Fin del Ejemplo 1.21
En el programa anterior, el string 'Bienvenido a IBM' es almacenado en otro string
llamado texto. StringReader se usa para leer carcter por carcter de texto.
Una vez vista la clase Reader y sus subclases; se pasa al otro tipo de clases, la clase
Writer y sus subclases.

7. La Clase Writer
Hasta ahora, se han visto formas de leer y escribir datos de tipo carcter en vez bytes.
Writer es una superclase abstracta para los flujos de caracteres que se usan para
escribir datos de tipo carcter. Las clases Writer estn adecuadas para manejar

Libro 2: Core Java

Unidad 1: Archivos y Flujos 119


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

caracteres Unicode y por esto son preferibles a los flujos de salida de objetos. La Figura
1.10 muestra a Writer y sus subclases.

Figura 1.10: La Clase Writer y Sus Subclases

Las subclases de Writer deben implementar write(char[], int, int), flush()


y close(). Sin embargo, ellas pueden sobrescribir otros mtodos provistos por
Writer para proporcionar la funcionalidad requerida.
La declaracin de esta clase es como sigue:
public abstract class Writer extends Object
A continuacin se estudian las distintas subclases de la clase Writer. Se comienza
con la clase BufferedWriter.

7.1 La Clase BufferedWriter


La clase BufferedWriter es un tipo de escritor, como otros flujos de tipo buffer, la
clase BufferedWriter mantiene un buffer interno de caracteres, que permite escribir
caracteres, lneas, arreglos y strings eficientemente.
El tamao del buffer puede ser especificado. Cuando el tamao del buffer no se
especifica, se usa el tamao por defecto. La clase BufferedWriter extiende a la
clase Writer.
BufferedWriter provee el mtodo newLine() que permite usar el separador de
lnea definido por la plataforma. La plataforma tiene su separador de lnea, especificado
mediante la propiedad del sistema llamada line.separator. Algunas plataformas
usan un carcter que es diferente del '\n' para especificar el fin de lnea. Por ello, es

Unidad 1: Archivos y Flujos

Libro 2: Core Java 120

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

preferible usar el mtodo newLine() definido en esta clase para marcar el fin de cada
lnea en la salida.
Usualmente cuando se hace una solicitud de escritura al Writer, este instruye al flujo
de carcter o byte subyacente para llevar a cabo esta solicitud. Por esto, un
BufferedWriter puede envolver a un escritor costoso, como un FileWriter o un
OutputStreamWriter, como se muestra:
PrintWriter pw = new PrintWriter(
new BufferedWriter(
new FileWriter("salida.txt")
)
);
Este cdigo enva de un PrintWriter a un archivo salida.txt para manejo de
buffer. En caso de que no se emplee el buffer, los caracteres sern escritos uno por uno
en el archivo. Esto puede ser ineficiente.
Considere el Ejemplo 1.22, que muestra el uso de la clase BufferedWriter:
Ejemplo 1.22
El cdigo Java comienza aqu...
1. import java.io.BufferedReader;
2. import java.io.BufferedWriter;
3. import java.io.FileWriter;
4. import java.io.IOException;
5. import java.io.InputStreamReader;
6. import java.io.PrintWriter;
7. import java.io.Writer;
8.
9. /*Definicion de la clase BufferedWriterEjemplo comienza aqui*/
10. public class BufferedWriterEjemplo {
11.
/* Metodo main comienza aqui */
12.
13.
14.

public static void main(String[] args) {


try {
String archivo = "Empleado.txt";

15.
16.
17.

/* Crear instancia de BufferedReader */


BufferedReader br;
br = new BufferedReader(

18.

new InputStreamReader(System.in)

Libro 2: Core Java

Unidad 1: Archivos y Flujos 121


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

19.
20.
21.

String empNombre;

22.
23.
24.

int empEdad;
float empSalario;
boolean empCasado;

25.
26.
27.

int estado = 0;

28.
29.

);

System.out.println("Ingrese datos de Empleado\n");


System.out.print("Nombre: ");

30.
31.
32.

empNombre = br.readLine();
empNombre = empNombre.trim();

33.
34.
35.

System.out.print("Edad: ");
empEdad = Integer.parseInt(br.readLine());

36.
37.
38.

System.out.print("Salario: ");
empSalario = Float.parseFloat(br.readLine());

39.
40.
41.

System.out.print("Casado (Si-0, No-1): ");


estado = Integer.parseInt(br.readLine());
if (estado == 0)

42.
43.
44.

empCasado = true;
else
empCasado = false;

45.
46.
47.

/* Crear instancia de Writer */


Writer salida = new FileWriter(archivo);

48.
49.
50.

/* Crear instancia de BufferedWriter */


BufferedWriter bw = new BufferedWriter(salida);

51.
52.

/* Crear instancia de PrintWriter */

53.
54.
55.

PrintWriter empSalida = new PrintWriter(bw);


/* Escribir en PrintWriter */

Unidad 1: Archivos y Flujos

Libro 2: Core Java 122

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

56.
57.
58.

empSalida.println(empNombre);
empSalida.println(empEdad);
empSalida.println(empSalario);

59.
60.
61.

empSalida.println(empCasado);

62.
63.
64.

empSalida.close();
System.out.println(
"Los datos del Empleado " +

/* Cerrar PrintWriter */

65.
66.

"fueron escritos en " +


archivo);

67.
68.
69.

} catch (NumberFormatException e) {
System.out.println("Numero invalido");
System.exit(0);

70.
71.
72.

} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);

73.
}
74.
}/* Metodo main termina aqui */
75. }/*Definicion de la clase BufferedWriterEjemplo termina aqui*/
El cdigo Java termina aqu
La salida son los detalles de un empleado almacenados en Empleado.txt.
Ingrese datos de Empleado
Nombre: Alvaro
Edad: 23
Salario: 200000
Casado (Si-0, No-1): 1
Los datos del Empleado fueron escritos en Empleado.txt
Fin del Ejemplo 1.22
En el programa del Ejemplo 1.22, los detalles del empleado como: nombre, edad,
salario y estado civil, se toman como entradas del usuario y se escriben al archivo
Empleado.txt.
Ahora, se estudiar la clase CharArrayWriter, que permite escribir arreglos de
caracteres a un flujo.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 123


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

7.2 La Clase CharArrayWriter


La clase CharArrayWriter se usa para escribir un arreglo de caracteres en un flujo
con un buffer interno. La clase CharArrayWriter extiende de la clase Writer. Los
datos escritos en este flujo pueden ser recuperados usando los mtodos
toCharArray() y toString().
Considere el Ejemplo 1.23, que muestra su uso:
Ejemplo 1.23
El cdigo Java comienza aqu...
1. import java.io.BufferedReader;
2. import java.io.CharArrayWriter;
3. import java.io.FileWriter;
4. import java.io.IOException;
5. import java.io.InputStreamReader;
6.
7. /*Definicion de la clase comienza aqui*/
8. public class CharArrayWriterEjemplo {
9.
10.
11.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

12.
13.

/* Crear instancia de CharArrayWriter */


CharArrayWriter caWriter = new CharArrayWriter();

14.
15.
16.

/* Crear instancia de BufferedReader */


BufferedReader br;

17.
18.
19.

br = new BufferedReader(
new InputStreamReader(System.in)
);

20.
21.
22.

String texto;
do {

23.
24.
25.
26.
27.

System.out.println(
"Ingrese una linea de texto: ");
texto = br.readLine();
texto = texto.trim();
} while (texto.length() == 0);

Unidad 1: Archivos y Flujos

Libro 2: Core Java 124

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

28.
29.
30.

Core Java

char buffer[] = new char[texto.length()];


texto.getChars(0, texto.length(), buffer, 0);

31.
32.
33.

caWriter.write(buffer);
System.out.println(

34.
35.
36.

"\nCharArrayWriter contiene:\n" +
caWriter.toString() +
"\n");

37.
38.

FileWriter fWriter = new FileWriter("Arreglo.txt");

39.
40.
41.

caWriter.writeTo(fWriter);
fWriter.close();
caWriter.reset();

42.
43.
44.

System.out.println(
"El contenido del arreglo " +

45.
46.
47.
48.
49.
50.

"fue escrito en Arreglo.txt");


} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);
}
}/* Metodo main termina aqui */

51. }/* Definicion de la clase termina aqui */


El cdigo Java termina aqu
La salida del programa es la siguiente:
Ingrese una linea de texto:
Bienvenido a IBM
CharArrayWriter contiene:
Bienvenido a IBM
El contenido del arreglo fue escrito en Arreglo.txt
Fin del Ejemplo 1.23
En el programa anterior, se toma una lnea como entrada del usuario. La lnea de
prueba es 'Bienvenido a IBM'. Esta lnea se escribe a un CharArrayWriter como un

Libro 2: Core Java

Unidad 1: Archivos y Flujos 125


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

arreglo de caracteres. Los contenidos del CharArrayWriter son luego escritos al


archivo Arreglo.txt.
A continuacin se presenta como trabaja la clase FilterWriter.

7.3 La Clase FilterWriter


FilterWriter, como el nombre lo sugiere, se usa para trabajar en el flujo de
caracteres manipulando los datos de salida basado en ciertos filtros (condiciones)
definidas por el usuario. La clase FilterWriter extiende Writer. Esta clase es
abstracta, y por esto la forma de filtrar tiene que estar implementada en la subclase.

7.4 La Clase OutputStreamWriter


La clase OutputStreamWriter acta como un puente entre los flujos de caracteres y
los de bytes. Esta clase extiende a la clase Writer.
Esto se ilustra en la Figura 1.11.

Figura 1.11: OutputStreamWriter como Puente entre Flujos de Carcter y Flujos de


Bytes

OutputStreamWriter se usa para convertir caracteres en bytes, de acuerdo al


esquema de codificacin de caracteres especificado. El usuario puede especificar el
esquema de codificacin usado o usar la codificacin por defecto de la plataforma,
definida por la propiedad de sistema file.encoding. Cada vez que se llama al
mtodo write, se invoca al convertidor de codificacin en los caracteres dados. Los
caracteres que son convertidos a bytes se guardan en un buffer antes de escribirse en
el flujo de salida. El tamao del buffer puede ser especificado, aunque el tamao por
defecto es generalmente suficiente para la mayora de los programas. Los caracteres
que se pasan a write() (antes de la conversin) no estn en un buffer, por lo que es
recomendable envolver un OutputStreamWriter por un BufferedWriter, como se
muestra en el siguiente cdigo, para mejorar la eficiencia:
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
System.out
)
);

Unidad 1: Archivos y Flujos

Libro 2: Core Java 126

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Considere el Ejemplo 1.24, que muestra el uso de OutputStreamWriter:


Ejemplo 1.24
El cdigo Java comienza aqu...
1.
2.
3.

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;

4.
5.
6.

import java.io.IOException;
import java.io.OutputStreamWriter;

7.
8.
9.

/*Definicion de la clase comienza aqui*/


public class OutputStreamWriterEjemplo {
/* Metodo main comienza aqui */

10.
11.
12.

public static void main(String[] args) {


try {
/* Debe ingresar el nombre del

13.
14.

archivo en la linea de comando */


if (args.length != 1) {

15.
16.
17.

System.err.println(
"Escriba en la linea de comando algo asi:");
System.err.println(

18.
19.
20.

"java OutputStreamWriterEjemplo archivo");


System.exit(0);
}

21.
22.
23.

FileReader fr = new FileReader(args[0]);


/* Crear instancia de OutputStreamWriter */

24.
25.
26.

System.out.println(
"Asociando OutputStreamWriter " +
"con la salida standard\n");

27.
28.
29.

OutputStreamWriter osw;
osw = new OutputStreamWriter(System.out);

30.
31.
32.

/* Crear instancia de BufferedWriter */


BufferedWriter bw = new BufferedWriter(osw);
int c = fr.read();

33.

while (c != -1) {

Libro 2: Core Java

Unidad 1: Archivos y Flujos 127


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

34.
35.
36.

bw.write(c);
c = fr.read();
} // Fin del ciclo while

37.
38.
39.

/* Cerrar FileReader y BufferedWriter */


fr.close();

40.
41.
42.

bw.close();
} catch (FileNotFoundException e) {
System.out.println(

43.
44.

"Archivo " +
args[0] +

45.
46.
47.

" no encontrado");
System.exit(0);
} catch (IOException e) {

48.
49.
50.

System.out.println(
"Error de Entrada/Salida");
System.exit(0);

51.
}
52.
}/* Metodo main termina aqui */
53. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
La salida del programa anterior ser la siguiente:
Asociando OutputStreamWriter con la salida standard
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entrada
Fin del Ejemplo 1.24
Este programa lee caracteres de un archivo y los imprime en la salida estndar.
El archivo de entrada contiene los siguientes datos:
El BufferedReader es un tipo de Reader(lector).
Se utiliza para leer los caracteres o Strings
desde el flujo de entradaAsociando
Asuma que se quiere leer los caracteres del archivo miArchivo.txt.
Al introducir el siguiente comando en la lnea de comandos:
Unidad 1: Archivos y Flujos

Libro 2: Core Java 128

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

java OutputStreamWriterEjemplo miArchivo.txt


Aqu,
OutputStreamWriterEjemplo es el nombre del archivo del programa Java.
miArchivo.txt es el nombre del archivo fuente del cual queremos leer los
caracteres.
A continuacin se explica la clase FileWriter.

7.5 La Clase FileWriter


FileWriter es una clase que nos permite escribir datos de tipo carcter en un
archivo. Esta clase mantiene un buffer interno al escribir los datos, extiende a la clase
OutputStreamWriter.
Considere el Ejemplo 1.25, que muestra su uso:
Ejemplo 1.25
El cdigo Java comienza aqu...
1.

import java.io.BufferedReader;

2. import java.io.FileWriter;
3. import java.io.IOException;
4. import java.io.InputStreamReader;
5. import java.io.Reader;
6. import java.io.StringReader;
7. import java.io.Writer;
8.
9. /*Definicion de la clase FileWriterEjemplo comienza aqui*/
10. public class FileWriterEjemplo {
11.
12.
13.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

14.
15.
16.

/* Crear instancia de BufferedReader */


BufferedReader br;
br = new BufferedReader(

17.
18.
19.

);
String texto;

20.
21.

/* Chequear que se ingresa algun texto */

Libro 2: Core Java

new InputStreamReader(System.in)

Unidad 1: Archivos y Flujos 129


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

22.
23.
24.

do {
System.out.println(
"Ingrese una linea de texto: ");

25.
26.
27.

texto = br.readLine();
texto = texto.trim();
} while (texto.length() == 0);

28.
29.
30.

/* Crear una instancia de Reader */


Reader entrada = new StringReader(texto);

31.
32.

/* Crear una instancia de Writer */

33.
34.
35.

Writer salida;
salida = new FileWriter("FileWriterEjemplo.txt");
int caracter;

36.
37.
38.

char c;
System.out.println(
"\nEl contenido del archivo es: ");

39.
40.
41.

/* Leer caracteres de Reader */


while ((caracter = entrada.read()) != -1) {

42.
43.
44.

/* Convertir los caracteres a mayuscula */


c = Character.toUpperCase((char) caracter);

45.
46.
47.

/* Se almacena en el archivo especificado */


salida.write(c);

48.
49.
50.

/* Mostrar el caracter en mayuscula


en la salida estandar */
System.out.print(c);

51.
52.
53.

54.
55.

System.out.println();

56.
57.
58.

/* Escribir caracter de fin de linea en el archivo */


salida.write('\n');
System.out.println(

/* Mostrar una linea en blanco */

Unidad 1: Archivos y Flujos

Libro 2: Core Java 130

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

59.
60.
61.

Core Java

"\nLa salida es escrita en el " +


"archivo FileWriterEjemplo.txt");

62.
63.
64.

/* Vaciar el writer y cerrar */


salida.flush();
salida.close();

65.
66.
67.

} catch (IOException e) {
System.out.println("Error de Entrada/Salida");
System.exit(0);

68.
69.

}
}/* Metodo main termina aqui */

70. }/* Definicion de la clase FileWriterEjemplo termina aqui */


El cdigo Java termina aqu
La salida de este programa es la siguiente:
Ingrese una linea de texto:
Bienvenido a IBM
El contenido del archivo es:
BIENVENIDO A IBM
La salida es escrita en el archivo FileWriterEjemplo.txt
Fin del Ejemplo 1.25
En el programa anterior, se toma del usuario una lnea. La lnea de prueba es
Bienvenido
a
IBM. Esta lnea es escrita a un archivo llamado
FileWriterEjemplo.txt usando el flujo FileWriter.

7.6 La Clase PipedWriter


La clase PipedWriter es una subclase de la clase Writer, se usa para utilizar una
tubera de caracteres en flujos de salida. Utilizar una tubera en un flujo de salida de
caracteres implica abrir un flujo de caracteres de salida en el tope de otro. Esta clase
tambin extiende a la clase Writer.

7.7 La Clase PrintWriter


La clase PrintWriter extiende a Writer. Este objeto escritor puede ser usado para
escribir datos string y datos objeto que estn formateados como string, etc. Esta clase
implementa todas las versiones del mtodo print que estn disponibles en
PrintStream.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 131


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Se pueden leer datos de un archivo usando un FileReader envuelto usando un


BufferedReader. Estos datos pueden escribirse a otro archivo, usando la misma
aplicacin Java, a travs de un FileWriter encapsulado usando un PrintWriter.
Esto se ilustra en la Figura 1.12.

Figura 1.12: Lectura y Escritura de un Archivo usando Flujos de Caracteres

Considere el Ejemplo 1.22, mostrado en la seccin 7.1 referente a La clase


BufferedWriter, este ejemplo muestra el uso de la clase PrintWriter.
1.1.1

7.7.1 Mtodos de la clase PrintWriter

El mtodo printf():
public PrintWriter printf(String formato, Object ... args)
Este mtodo provee gran poder y flexibilidad a la forma en que se ver la salida, tiene
muchas opciones y un nmero variable de parmetros. Es un mtodo de salida usado
para escribir una cadena de caracteres formateada utilizando una cadena de formato y
una lista de argumentos especificados. Si el flujo automtico es habilitado, las llamadas
a este mtodo vaciarn hacia el buffer de salida.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 132

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Una invocacin de este mtodo de la forma out.printf(formato, args) se


comporta exactamente de la misma manera que la invocacin out.format(formato,
args).
Parmetros:
formato Es una cadena de formato la cual puede contener texto fijo y uno o ms
especificadores de formato embedidos.
args Son argumentos referenciados por los especificadores de formato en la
cadena de formato. Si hay ms argumentos que especificadores de formato, los
argumentos extras son ignorados. La cantidad de argumentos es variable y puede ser
cero. El nmero mximo de argumentos es limitado por la mxima dimension de un
arreglo Java tal como est definido por la Especificacin de la Mquina Virtual de Java.
El comportamiento sobre un argumento null depende de la conversin (general, de
characteres, numrica, fecha/hora, porcentual).
El mtodo printf() con otra firma:
printf(Locale l, String format, Object ... args)
Es un mtodo de conveniencia que se usa para escribir una cadena de caracteres
formateada para la clase Writer utilizando los argumentos y la cadena de formatos
especificados. Si el flujo automtico es habilitado, las llamadas a este mtodo vaciarn
el buffer de salida.
Una invocacin de este mtodo de la forma out.printf(l, formato, args) se
comporta exactamente de la misma manera que la invocacin out.format(l,
formato, args)

Parmetros:
l Es el objeto Locale para aplicar durante el formateo. Si l es null entonces no se
aplica la localizacin.
formato Es una cadena de formato la cual puede contener texto fijo y uno o ms

especificadores de formato embedidos.


args Son argumentos referenciados por los especificadores de formato en la

cadena de formato. Si hay ms argumentos que especificadores de formato, los


argumentos extras son ignorados. La cantidad de argumentos es variable y puede ser
cero. El nmero mximo de argumentos es limitado por la mxima dimension de un
arreglo Java tal como est definido por la Especificacin de la Mquina Virtual de Java.
El comportamiento sobre un argumento null depende de la conversin (general, de
characteres, numrica, fecha/hora, porcentual).
Existe tambin un mtodo llamado format, el cual se comporta exactamente de la
misma manera que el mtodo printf. El parmetro de este mtodo es:
Libro 2: Core Java

Unidad 1: Archivos y Flujos 133


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

format(String formato, Object... args)

7.8 La Clase StringWriter


La clase StringWriter es una subclase de la clase Writer. El string que se quiere
escribir a un flujo, primero se le asigna a un buffer. Los contenidos de este buffer son
usados para construir un string y este ltimo se usa finalmente para escribir en el flujo
de caracteres.

8. La Clase Scanner
La clase Scanner permite hacer lectura formateada desde un flujo de entrada. Esta
clase est presente a partir de Java 5.0. La lectura se basa en un delimitador, que por
defecto es uno o varios espacios en blanco.
Considere el Ejemplo 1.26, que muestra su uso:
Ejemplo 1.26
El cdigo Java comienza aqu...
1.
2.

import java.util.Scanner;

3. /*Definicion de la clase ScannerEjemplo comienza aqui*/


4. public class ScannerEjemplo {
5.
/* Metodo main comienza aqui */
6.
7.
8.

public static void main(String[] args) {


System.out.println("Ingrese Nombre y Edad: ");

9.
10.
11.

/* Crear instancia de Scanner */


Scanner entrada = new Scanner(System.in);

12.
13.
14.

/* Extrae del flujo un String */


String nombre = entrada.next();

15.
16.
17.

/* Extrae del flujo un entero */


int edad = entrada.nextInt();

18.
19.

/* Cierre del flujo */


entrada.close();

20.
Unidad 1: Archivos y Flujos

Libro 2: Core Java 134

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

21.
22.
23.

Core Java

/* Se muestra por la salida estandar lo capturado */


System.out.println("Su Nombre es: " + nombre);
System.out.println("Su Edad es: " + edad);

24.
}/* Metodo main termina aqui */
25. }/* Definicion de la clase ScannerEjemplo termina aqui */
El cdigo Java termina aqu
La salida de este programa es la siguiente:
Ingrese Nombre y Edad:
Pedro <ENTER>
25 <ENTER>
Su Nombre es: Pedro
Su Edad es: 25
Fin del Ejemplo 1.26
En el programa anterior, se toma del usuario su nombre y su edad. Esta informacin se
extrae a travs de los mtodos next() y nextInt() de la clase Scanner. Luego se
cierra el flujo y se procede a mostrar el resultado de los datos ingresados por el usuario.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 135


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Resumen
Ahora que ha completado esta unidad, usted debe ser capaz de:

Explicar la clase File.

Describir FileDescriptor.

Explicar los flujos.

Explicar los diferentes tipos de flujos de caracteres.

Explicar los diferentes tipos de flujos de bytes.

Describir la forma de trabajo con acceso aleatorio en archivos.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 136

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 1: Examen de Autoevaluacin


1) Los objetos de la clase File son inmutables.
a) Verdadero
b) Falso
2) Los objetos de la clase FileDescriptor se pueden usar para representar
a) Un archivo abierto
b) Un conector abierto
c) Una fuente o receptor de bytes de datos
d) Todas las anteriores
3) Los flujos se pueden usar para leer cul de los siguientes tipos de datos
a) Un objeto
b) Un string
c) Sonido
d) Todas las anteriores
4) Cul de los siguientes flujos permite acceder a los datos en forma secuencial?
a) Flujos de Caracteres
b) Flujos de Bytes
c) Ambos anteriores
d) Ninguno de los anteriores
5) Qu clase permite tener acceso aleatorio en archivos?
a) File
b) FileDescriptor
c) RandomFileAccess
d) Ninguna de las anteriores
6) Se pueden crear objetos de la clase Reader para leer caracteres.
a) Verdadero
b) Falso
7) Se puede especificar el tamao del buffer interno de la clase BufferedReader.
a) Verdadero
b) Falso

Libro 2: Core Java

Unidad 1: Archivos y Flujos 137


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

8) Cul de las siguientes opciones son correctas en relacin BufferedReader?


a) BufferedReader
br
=
InputStreamReader(System.in));
b) BufferedReader br
"archivo.txt"));
c) BufferedReader
br
"archivo.txt"));
d) BufferedReader br
"archivo.txt"));

new

BufferedReader(new

= new BufferedReader(new FileReader(


=

new

BufferedReader(new

File(

= new BufferedReader(new InputStream(

9) Cul de los siguientes mtodos se pueden usar para obtener los datos escritos
usando un ByteArrayOutputStream?
a) toByteArray()
b) toString()
c) toArray()
d) Ninguno de los anteriores
10) La clase RandomAccessFile se usa para ____________.
a) Lectura de archivos
b) Escritura a archivos
c) Ambos anteriores
d) Ninguna de las anteriores

Unidad 1: Archivos y Flujos

Libro 2: Core Java 138

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Respuestas a la Unidad 1: Examen de Autoevaluacin


1) a
2) d
3) d
4) c
5) d
6) b
7) a
8) a y b
9) a y b
10) c

Libro 2: Core Java

Unidad 1: Archivos y Flujos 139


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 2: Laboratorio de Archivos y


Flujos
Objetivos del Aprendizaje
Al final de esta unidad, usted ser capaz de:

Crear archivos.

Aprender a leer de y escribir a archivos.

Desarrollar programas Java para acceder directorios y subdirectorios.

Libro 2: Core Java

Unidad 2: Laboratorio de Archivos y Flujos 141


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Ejercicios de Laboratorio
1) Escribir un programa en Java que lea el contenido de un archivo e invierta cada
palabra leda y la escriba a un archivo destino, cuyo contenido se lee y muestra
usando el mtodo printf de la clase PrintWriter.
Recomendaciones tiles:

Escriba una clase llamada Inversor.

Abra un archivo fuente cuyos contenidos sern ledos.

Abra un archivo destino en el cual se van a escribir los contenidos.

Use FileInputStream para leer del archivo.

Despus de leer una palabra (conjunto de caracteres seguido de un espacio en


blanco) convertirla a un String, e invertirla usando el mtodo invertir().

El string invertido se convierte a un arreglo de caracteres y se escribe al archivo


destino usando FileOutputStream.

Los contenidos del archivo destino son ledos usando FileInputStream e


impresosusando el mtodo printf de la clase PrintWriter.

2) Escribir un programa en Java que lea el contenido de los archivos dat1 y dat2,
ambos con el mismo nmero de lneas. Las lneas de dat1 y dat2 se leen
alternativamente y se escriben a otro archivo dat3. Finalmente, el contenido del
archivo dat3 se imprime usando el mtodo printf de la clase PrintWriter.
Recomendaciones tiles:
Escriba una clase llamada Fusion.

Abra un FileReader encapsulado usando un BufferedReader en los


archivos dat1.txt y dat2.txt.

Abra un FileWriter en dat3.txt.

Lea una lnea de dat1.txt y una de dat2.txt usando el mtodo


readLine() de FileReader.

Escriba las lneas ledas a dat3.txt usando el mtodo write() de


FileWriter.

Cierre todos los flujos.

Abra un FileReader envuelto con un BufferedReader en dat3.txt.

Lea los contenidos de dat3.txt usando el mtodo readLine() FileReader


e imprmalos usando el mtodo printf de la clase PrintWriter.

Cierre los flujos.

Unidad 2: Laboratorio de Archivos y Flujos

Libro 2: Core Java 142

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

3) Escribir un programa en Java que liste todos los subdirectorios del directorio actual.
Recomendaciones tiles:

Escriba una clase llamada Directorio.

Declare una variable string e inicialcela con la ruta del directorio actual.

Cree un objeto file con la variable String como parmetro.

Declare un arreglo de string e inicialcelo con la lista de subdirectorios y archivos


del objeto file representando el directorio actual usando el mtodo list().

Comience un ciclo for que se ejecute tantas veces como nmero de elementos
tenga el arreglo de string.

Cree un objeto File que represente al directorio actual y un elemento del


arreglo string como parmetros.

Cada vez que se ejecuta el ciclo el ndice en el arreglo de string se incrementa


en uno.

Revise si el objeto File recin creado representa a un directorio e imprima el


nombre del subdirectorio en la salida estndar.

4) Escribir un programa en Java que lea el contenido de un archivo que tenga la


siguiente estructura:
123
456
789

pedro
maria
juan

s2m
s3t
s1n

Para ello haga uso de la clase Scanner. Finalmente, el contenido de cada


lneadel archivo se imprime usando el mtodo printf de la clase PrintWriter.
Recomendaciones tiles:

Escriba una clase llamada LectorArchivo.

Cree un mtodo esttico que reciba un String que ser el nombre del archivo.

Cree un objeto File con la variable String como parmetro.

Si el archivo existe, cree un objeto Scanner que reciba como parmetro el


objeto File.

Mientras exista una nueva lnea en el archivo, extraiga los valores del mismo
teniendo en cuenta los tipos de datos que representa cada columna e
imprimalos usando el mtodo printf de la clase PrintWriter.

Recuerde cerrar el flujo del objeto Scanner despus de culminar la lectura del
archivo.

Luego llame al mtodo esttico, pasandole el nombre del archivo a leer.

Libro 2: Core Java

Unidad 2: Laboratorio de Archivos y Flujos 143


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 3: Serializacin de Objetos


Objetivos del Aprendizaje
Al final de esta unidad, usted ser capaz de:

Explicar la serializacin de objetos.

Explicar la interfaz Serializable.

Explicar la interfaz Externalizable.

Explicar la clase ObjectOutputStream.

Explicar la clase ObjectInputStream.

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 145


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

1. Introduccin
En Java, se trabaja principalmente con clases y objetos. Los objetos persisten en la
memoria hasta tanto el programa est activo. Una vez que el programa completa su
ejecucin, los objetos son destruidos. Sin embargo, es posible almacenar un objeto en
un archivo durante la primera ejecucin de un programa, de forma que el valor de dicho
objeto est disponible posteriormente. Los objetos pueden ser reconstruidos antes de la
segunda ejecucin del programa al recuperar sus valores del archivo donde se
almacenaron. Este proceso de almacenar y recuperar el valor de un objeto se realiza a
travs de la serializacin de objetos. A continuacin se estudiar esto en detalle.

2. Serializacin de Objetos
La serializacin de objetos es el proceso por el cual el estado actual de un objeto puede
ser guardado en forma persistente. Tambin se puede recuperar el objeto con su estado
de la misma forma en que se guardo. El proceso de almacenar el objeto se llama
serializacin de objetos, mientras que el proceso de leer el objeto y recuperar el valor
que haba sido almacenado se llama deserializacin de objetos.
La serializacin de objetos, aunque es un concepto simple, tiene muchos usos. La
serializacin de objetos se usa al pasar objetos a travs de flujos, en RMI y en
persistencia ligera, que se estar discutiendo ms adelante en esta unidad.
La Figura 3.1 muestra como ocurre la serializacin de objetos en Java.

Figura 3.1: Serializacin de Objetos

Hasta tanto el programa este ejecutndose, los objetos viven dentro de la JVM. A travs
de la serializacin, los objetos se hacen persistentes fuera de la JVM an despus de
que el programa finalice su ejecucin. La serializacin ayuda a escribir y leer grafos de
objetos de la memoria al sistema de archivos y recuperar las asociaciones de memoria
del sistema de archivos a los objetos. La serializacin de objetos guarda los siguientes
detalles acerca de un objeto que esta siendo serializado:

Tipo del Objeto.

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 146

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Informacin Interna.

Referencias a otros objetos.

Core Java

Luego de esta introduccin a la serializacin de objetos, se discuten las aplicaciones de


la serializacin de objetos.

3. Aplicaciones de la Serializacin de Objetos


Existen innumerables aplicaciones basadas en la serializacin de objetos. Las
siguientes son tres aplicaciones que hacen uso de sta:
Aplicaciones Cliente-Servidor.
Invocacin a Mtodos Remotos (Remote Method Invocation RMI).
Persistencia de objetos.

3.1 Aplicaciones Cliente-Servidor


Las aplicaciones Cliente-Servidor necesitan intercambiar datos. Tpicamente, los datos
intercambiados son de tipo texto. Si los objetos van a ser intercambiados, se usar la
serializacin de objetos. Los objetos pueden ser serializados antes de ser enviados por
la red y pueden ser reconstruidos una vez que sean recibidos por el mtodo remoto.

3.2 Invocacin a Mtodos Remotos (RMI)


La serializacin de objetos puede ser usada en RMI, que trata de la comunicacin entre
objetos a travs de conectores (sockets). RMI provee un mecanismo por el cual un
mtodo en un objeto puede invocar a un mtodo en otro objeto residente en una JVM
diferente. En este caso, los objetos necesitan ser pasados por la red y por esto tienen
que ser serializados.

3.3 Persistencia de Objetos


Persistencia involucra el almacenaje de un objeto. Asuma que se necesita que los datos
contenidos en un objeto sean persistentes. Una forma de almacenar un objeto es
almacenndolo en un archivo, con delimitadores, pero esto involucra muchas
manipulaciones de cadenas de caracteres y de archivo. La otra forma, es lograr la
persistencia a travs de la serializacin de objetos. Se pueden guardar objetos en forma
persistente durante una ejecucin del programa y recuperarlos durante otra ejecucin.
Una vez entendidos los principios bsicos de la serializacin y sus usos, se ver como
Java implementa la serializacin.

4. Implementando Serializacin en Java


La lectura y escritura de objetos en Java se lleva a cabo con la ayuda de dos flujos
presentes en el paquete java.io
son estos: ObjectInputStream y

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 147


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

ObjectOutputStream. Estas clases son similares a los otros flujos de entrada y


salida de Java.
Las distintas clases que se usan en la serializacin de objetos, se listan en la Figura 3.2
con su jerarqua.

Figura 3.2: Clases e Interfaces en la Serializacin de Objetos

En esta unidad se aprender la forma de escribir clases cuyas instancias se pueden


serializar mediante la interfaz Serializable. Luego se ver cmo tener control
explcito sobre el proceso de serializacin mediante la interfaz Externalizable.
Tambin se estudiar la forma de serializar objetos con la clase
ObjectOutputStream y recuperar los objetos serializados con la clase
ObjectInputStream. Se comenzar con la interfaz Serializable.

4.1 La interfaz Serializable


La clase cuyas instancias pueden ser serializadas en Java, tiene que implementar la
interfaz java.io.Serializable. La interfaz Serializable es una interfaz vaca.
Una interfaz vaca es aquella que no contiene mtodos. Se usa slo para identificar la
semntica de la serializacin. Serializable es una interfaz marcadora y marca que la
clase tiene la propiedad de la serializacin.
El estado de un objeto no puede ser serializado o de-serializado sin implementar la
interfaz Serializable. Todas las subclases de una clase que implementa la interfaz
Serializable pueden ser serializadas.
La interfaz Serializable tiene que ser usada despus de la clusula implements
en la declaracin de la clase, como se muestra a continuacin:
class MiClase implements Serializable{
Unidad 3: Serializacin de Objetos

Libro 2: Core Java 148

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

// ...
}
En el caso de una relacin de herencia, si una superclase de una clase no es
serializable, entonces la subclase puede tomar la responsabilidad de serializar y
recuperar las variables public, protected y package de la superclase. Las variables
private no son serializables de esta forma.
Nota: Ambas la superclase y la subclase deben estar presentes en el mismo paquete
para lograr esto.
Una subclase puede tomar la responsabilidad de serializar las variables slo cuando la
superclase tiene un constructor que no toma ningn parmetro para inicializar su
estado, y es accesible por la subclase. Si existe una violacin a la regla anterior, se
detectar slo en tiempo de ejecucin.
Las variables que son serializadas son aquellas que se usan para construir el objeto.
Los campos en la superclase del objeto serializado son inicializados por el cdigo en el
constructor public o protected.
Cuando se serializa un objeto, se recorre la jerarqua de clases de este objeto para
serializar los campos y mtodos heredados por este objeto. En la jerarqua de herencia
de este objeto, se puede encontrar una clase que no implemente la interfaz
Serializable y por esto no puede ser serializada. Cuando esto ocurre, se lanza una
NotSerializableException. Durante la serializacin y deserializacin de objetos,
algunas clases pueden necesitar manejar situaciones excepcionales en una forma
especial. Estas clases pueden implementar los mtodos writeObject() y
readObject().
Los mtodos readObject() y writeObject() sirven bsicamente para personalizar
el proceso de serializacin. El mtodo writeObject() permite controlar la forma de
guardar el estado del objeto serializado en ObjectOutputStream y el estado de ese
objeto se puede restaurar usando el mtodo readObject() usando
ObjectInputStream. Se puede usar el mtodo writeObject() o los mtodos
declarados en la interfaz DataOutput para escribir al ObjectOutputStream para
serializar los campos del objeto.
Si no se quiere controlar la manera en la que los campos son serializados y es
suficiente usar el mtodo por defecto de serializacin, se puede usar el mtodo
defaultWriteObject(). Si se usa este mtodo, los campos que pertenecen a la
superclase o a la subclase de la clase en consideracin no sern serializados.
El mtodo readObject() restaura el estado del objeto que fue serializado usando el
mtodo writeObject() correspondiente. Tambin permite actualizar el estado del
objeto luego de haber sido restaurado.

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 149


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

La Figura 3.3. muestra como ObjetoEjemplo implementa la interfaz Serializable,


colocando as, al objeto listo para serializacin.

Figura 3.3: ObjetoEjemplo Listo para Serializacin

Se puede usar el mtodo defaultReadObject() para recuperar los campos que no


sean static y no transient en la deserializacin. Este mtodo asigna los campos
restaurados del objeto guardado a los campos correspondientes en el objeto actual. A
este mtodo no le concierne el estado de las superclases o subclases de la clase
actual. Usando el mtodo readObject() para leer del ObjectInputStream, se
puede restaurar el estado de cada campo.
Se puede tambin sustituir el objeto a ser usado cuando se escribe al flujo de salida. En
estos casos, se usa el mtodo writeReplace(). ste puede ser accedido desde un
mtodo en la clase cuyo objeto est siendo serializado. Por esto, el mtodo
writeReplace() puede acceder a las variables private, protected, package y
public de la clase.
Cuando se accede al mtodo writeReplace() desde una subclase, se siguen las
reglas de accesibilidad de Java para los diferentes especificadores de acceso.
Similarmente, cuando se tiene que sustituir el objeto a ser usado, cuando se lee de un
flujo de entrada, se puede usar el mtodo readResolve(). Este mtodo puede ser
accedido desde un mtodo en la clase cuyo objeto esta siendo deserializado. Por esto,
el mtodo readResolve() puede acceder a las variables private, protected,
package, y public de la clase actual. Cuando se accede al mtodo readResolve()

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 150

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

desde una subclase, se siguen las reglas de accesibilidad para los diferentes
especificadores de acceso de Java.
No se puede serializar los campos de un objeto que no implemente la interfaz
Serializable. Una clase no serializable puede tener una subclase serializable. En
este caso, la clase no serializable necesita tener un constructor que no tome ningn
argumento, para inicializar sus campos. La subclase de esta clase no serializable debe
hacerse cargo de serializar los campos de esta clase y recuperarlos. Usualmente, los
campos de la superclase sern accesibles (public, protected, package). Si los
campos no son accesibles, la superclase deber tener los mtodos get y set que
puedan ser usados para serializar y recuperar los campos de la superclase no
serializable.

4.2 La Interfaz Externalizable


La interfaz Serializable es una interfaz marcadora, realiza la mayora de la actividad
durante la serializacin. Maneja implcitamente los campos con varios modificadores de
acceso, campos que son compartidos con las clases herederas y las clases bases, etc.
Si se quiere tener un mayor control y soluciones de serializacin personalizadas, se
debe acudir a la externalizacin, es decir, implementar la interfaz Externalizable, en
vez de la interfaz Serializable.
La interfaz Externalizable se aplica cuando una clase necesita coordinarse
explcitamente con su superclase para serializarse a s misma. Implementar una interfaz
Externalizable da un control completo y explcito del proceso de serializacin de la
clase. A diferencia de las clases que implementa la interfaz Serializable, la clase
ObjectOutputStream automticamente guarda slo la identidad de la clase que
implementa la interfaz Externalizable. La clase que implementa la interfaz
Externalizable es responsable de serializar y deserializar su estado y lo hace en
coordinacin con su superclase.
La interfaz Externalizable extiende a la interfaz Serializable, tiene dos mtodos
ampliamente usados cuando se utiliza la externalizacin writeExternal() y
readExternal(). Estos mtodos son implementados de manera que proporcionan un
control completo del formato de la serializacin. Esto es particularmente til en el caso
de la relacin de herencia donde los campos de la superclase son tambin serializados.
En la interfaz Serializable, los mtodos que se usan para escribir los detalles del
objeto en el almacenamiento permanente y para leer del almacenamiento permanente,
se encargan de lo relacionado con el estado del objeto y de sus superclases. En el caso
de la interfaz Externalizable, los mtodos writeExternal() y readExternal()
se implementan por el usuario para coordinar explcitamente con la superclase para
guardar el estado del objeto.
Las interfaces Serializable y Externalizable se usan tambin en los
mecanismos para persistencia de objetos. Cuando se usa un formato definido fuera de

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 151


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

la clase, los mtodos readExternal() y writeExternal() son los nicos


responsables de preservar este formato particular cuando se leen y escriben objetos.
Nota: Estos dos mtodos deben ser declarados como pblicos. Dado que los mtodos
son declarados como public, existe un riesgo de hacer posible que un objeto externo
escriba o lea informacin en el objeto Externalizable. Por lo que, es recomendable
usar estos dos mtodos slo cuando no exista riesgo de seguridad.
En una clase, los especificadores de control se usan para restringir el acceso a las
variables y mtodos. Las variables que tienen informacin sensible no deben ser
serializadas. En estos casos, se puede recurrir a variables transitorias (transient).
Esto brinda una solucin segura en el caso de la interfaz Serializable. Se debe
poner un cuidado especial en el caso de la interfaz Externalizable.
Adicionalmente, los objetos que implementan la interfaz Externalizable son
propensos a ser sobrescritos dado que el mtodo readExternal() es pblico. Un
desarrollador puede invocar al mtodo readExternal(), y pasar cualquier flujo definido
por el usuario para leer los valores del objeto. Al hacer esto, el objeto destino es
reinicializado.
Por todo lo anterior, un comportamiento conservador debe tomarse cuando se serializan
objetos. No se debe confiar en que los flujos slo tienen representaciones vlidas de
objetos. Para este propsito, se debe asegurar que el estado sensible de un objeto no
pueda ser recuperado y que la clase debe reverificar los contenidos que son
recuperados.
La serializacin de objetos no debe realizarse hasta que sea absolutamente necesario.
En caso de implementar estas interfaces, los campos sensibles que no deben ser
serializados deben ser manejados con precaucin.
Las posibles formas de asegurar que no ocurra la serializacin innecesaria de objetos
son las siguientes:
Marcar los campos como private o transient previene que sean serializados.
Los mtodos getter y setter de los campos que no deben ser serializados deben lanzar
NotSerializableException, para que el proceso de serializacin termine.
Las clases que no necesitan ser serializadas no deben implementar la interfaz
Serializable o Externalizable.
Nota: Los mtodos writeReplace() y readResolve() pueden tambin ser usados
para crear objetos duplicados de la clase que implementa la interfaz Externalizable.

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 152

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

4.3 La Clase ObjectOutputStream


La clase ObjectOutputStream se usa para escribir tipos de datos que estn
contenidos en objetos Java a un a clase OutputStream. Escriben la representacin en
memoria de los objetos a la clase OutputStream. Los objetos Java escritos usando
ObjectOutputStream pueden leerse usando ObjectInputStream. Para guardar
los objetos en forma persistente se puede usar un archivo donde el flujo escribe su
salida.
Se puede usar la clase ObjectOutputStream para serializar objetos, datos cadenas y
tambin para tipos de datos primitivos.
Slo los objetos de las clases que implementan la interfaz java.io.Serializable,
permiten que las clases almacenen y recuperen la informacin mientras el flujo se lee o
se escribe. El nombre y la firma de la clase, los valores de los campos y arreglos del
objeto, y la clausura de cualquier otro objeto referenciado por los objetos iniciales se
codifican durante el proceso de serializacin.
Se puede usar el mtodo writeObject() cuando se quiere escribir un objeto a un
flujo. An, los strings, arreglos y los tipos primitivos son tratados como objetos y son
escritos usando el mtodo writeObject(). Para recuperar los objetos guardados se
deben leer los mismos tipos en el orden en que fueron almacenados. Para los tipos de
datos primitivos, se tienen mtodos como: writeIn()t, writeFloat(), etc.
Sin embargo, una discusin ms profunda sobre los mtodos que estn disponibles en
esta clase esta fuera del alcance de esta discusin.
El Ejemplo 3.1 ilustra el uso de ObjectOutputStream para serializar los campos de
objetos.
Ejemplo 3.1
Este programa acepta los detalles de un empleado del usuario y los escribe en el
archivo ObjetoEmpleado.txt.
El cdigo Java comienza aqu
1. import java.io.BufferedReader;
2. import java.io.FileOutputStream;
3. import java.io.IOException;
4. import java.io.InputStreamReader;
5. import java.io.ObjectOutputStream;
6.
7. /*Definicion de la clase comienza aqui*/
8. public class ObjectOutputStreamEjemplo {

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 153


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

9.
10.
11.

Gua del Estudiante

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

12.
13.
14.

// Crear una instancia de FileOutputStream;


FileOutputStream fos;
fos = new FileOutputStream("ObjetoEmpleado.txt");

15.
16.
17.

// Crear una instancia de ObjectOutputStream


ObjectOutputStream oos;

18.
19.

oos = new ObjectOutputStream(fos);

20.
21.
22.

// Crear una instancia de BufferedReader


BufferedReader br;
br = new BufferedReader(

23.
24.
25.

new InputStreamReader(System.in)
);

26.
27.
28.

// Declaracin de variables
long empCodigo;
String empNombre;

29.
30.
31.

int empEdad;

32.
33.
34.

System.out.println(
"Ingrese los datos del Empleado:");

35.
36.
37.

System.out.print("Codigo: ");
empCodigo = Long.parseLong(br.readLine());

38.
39.
40.

System.out.print("Nombre: ");
empNombre = br.readLine().trim();

41.
42.

System.out.print("Edad: ");
empEdad = Integer.parseInt(br.readLine());

43.
44.
45.

// Escribir los detalles del empleado en el archivo


oos.writeLong(empCodigo);

// Obtener la entrada del usuario

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 154

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

46.
47.
48.

oos.writeObject(empNombre);
oos.writeInt(empEdad);

49.
50.
51.

System.out.println(
"Los datos del empleado fueron " +
"escritos en ObjetoEmpleado.txt");

52.
53.
54.

// Cerrar el ObjectOutputStream
oos.flush();

55.
56.

oos.close();
} catch (NumberFormatException e) {

57.
58.
59.

System.out.println("Valor invalido");
System.exit(0);
} catch (IOException e) {

60.
61.
62.

System.out.println("Error de Entrada/Salida");
System.exit(0);
}

63.
}/* Metodo main termina aqui */
64. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
El programa anterior acepta detalles del empleado y escribe el siguiente texto en el
archivo ObjetoEmpleado.txt.
Ingrese los datos del Empleado:
Codigo: 123
Nombre: Alvaro
Edad: 23
Los datos del empleado fueron escritos en
ObjetoEmpleado.txt
ObjetoEmpleado.txt contiene los siguientes datos:

Fin del Ejemplo 3.1


A continuacin se estudia la clase ObjectInputStream.

4.4 La Clase ObjectInputStream


La clase ObjectInputStream permite la deserializacin de datos primitivos u objetos
escritos por ObjectOutputStream. Estos dos flujos cuando se usan con
Libro 2: Core Java

Unidad 3: Serializacin de Objetos 155


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

FileInputStream y FileOutputStream proporcionan almacenamiento persistente


de objetos.
Durante la deserializacin, se crean nuevos objetos; por lo tanto los viejos objetos no
son sobrescritos. La memoria es asignada a los objetos nuevos y es inicializada en null.
Los campos individuales que son ledos de la clase ObjectInputStream son
asignados a los campos apropiados en el nuevo objeto. Si alguna excepcin ocurre
durante la deserializacin, la clase ObjectInputStream la captura y el proceso de
lectura concluye.
Se puede usar el mtodo readObject() para leer objetos de ObjectInputStream.
El mecanismo de conversin proporcionado por Java se usa para obtener los objetos
del tipo deseado. ObjectInputStream tambin permite leer tipos primitivos de datos.
En caso de los tipos definidos por el usuario, son serializados usando writeObject(),
y el correspondiente mtodo readObject() se usa para deserealizar los datos en
forma apropiada. Al mtodo readObject() no le conciernen los estados (campos) de
las superclase o subclases de la clase actual.
Observe a continuacin el Ejemplo 3.2.
Ejemplo 3.2
Este ejemplo muestra el uso de ObjectInputStream para recuperar los campos de
los objetos.
El cdigo Java comienza aqu
1.
2.

import java.io.FileInputStream;
import java.io.FileNotFoundException;

3.
4.

import java.io.IOException;
import java.io.ObjectInputStream;

5.
6.
7.

/*Definicion de la clase comienza aqui*/


public class ObjectInputStreamEjemplo {

8.
9.
10.

/* Metodo main comienza aqui */


public static void main(String[] args) {
try {

11.
12.
13.

// Crear una instancia de FileInputStream


FileInputStream fis;
fis = new FileInputStream("ObjetoEmpleado.txt");

14.
15.

// Crear una instancia de ObjectInputStream

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 156

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

16.
17.
18.

ObjectInputStream ois;
ois = new ObjectInputStream(fis);

19.
20.
21.

// Declaracion de variables
long empCodigo;
String empNombre;

22.
23.
24.

int empEdad;
System.out.println(

25.
26.

"Leyendo los datos del Empleado " +


"del archivo ObjetoEmpleado.txt\n");

27.
28.
29.

// Leer valores del objeto del archivo


empCodigo = ois.readLong();

30.
31.
32.

empNombre = (String) ois.readObject();


empEdad = ois.readInt();

33.
34.
35.

/* Mostrar los valores del empleado


en la salisda estandar */
System.out.println("Datos del Empleado");

36.
37.
38.

System.out.println("Codigo: " + empCodigo);


System.out.println("Nombre: " + empNombre);
System.out.println("Edad: " + empEdad);

39.
40.
41.

} catch (ClassNotFoundException e) {
System.out.println(e);
} catch (FileNotFoundException e) {

42.
43.
44.

System.out.println("No se encuentra el archivo");


System.exit(0);
} catch (IOException e) {

45.
46.
47.

System.out.println("Error de Entrada/Salida");
System.exit(0);
}

48.
}/* Metodo main termina aqui */
49. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 157


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Este programa usa el archivo ObjetoEmpleado.txt como entrada. El contenido del


archivo es lo que se obtiene como salida del programa que ilustra el uso de
ObjectOutputStream en el Ejemplo 3.1.
La salida del programa es la siguiente:
Leyendo los datos del Empleado del archivo ObjetoEmpleado.txt
Datos del Empleado
Codigo: 123
Nombre: Alvaro
Edad: 23
Fin del Ejemplo 3.2
El Ejemplo 3.2 ilustr como los campos que son almacenados en objetos pueden ser
recuperados. A continuacin otro ejemplo, que almacena y recupera los campos.
Ejemplo 3.3
Este ejemplo muestra como usar ObjectOutputStream y ObjectInputStream para
una clase que implementa la interfaz java.io.Serializable, para almacenar y
recuperar los campos de la clase Serializable.
El cdigo Java comienza aqu
1.
2.
3.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

4.
5.
6.

import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;

7.
8.
9.

import java.io.ObjectOutputStream;
import java.io.Serializable;

10. /* Definicion de la clase Empleado comienza aqui */


11. class Empleado implements Serializable {
12.
// Datos miembros
13.
14.
15.

private int codigo;


private String nombre;
private float sueldo;

16.
17.
18.

/* Constructor Empleado comienza aqui */


public Empleado(int codigo, String nombre, float sueldo) {

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 158

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

19.
20.
21.

Core Java

super();
this.codigo = codigo;
this.nombre = nombre;

22.
23.
24.

this.sueldo = sueldo;
}/* Constructor Empleado termina aqui */

25.
26.
27.

/* Metodo toString comienza aqui */


public String toString() {
StringBuffer datos = new StringBuffer();

28.
29.

datos.append("***Datos del empleado***\n");

30.
31.
32.

datos.append("Codigo: " + getCodigo() + "\n");


datos.append("Nombre: " + getNombre() + "\n");
datos.append("Sueldo: " + getSueldo());

33.
34.
35.

return datos.toString();
}/* Metodo toString termina aqui */

36.
37.
38.

public int getCodigo() {


return codigo;

39.
40.
41.

}
public void setCodigo(int codigo) {
this.codigo = codigo;

42.
43.
44.

45.
46.
47.

public String getNombre() {


return nombre;
}
public void setNombre(String nombre) {

48.
49.
50.

this.nombre = nombre;
}

51.
52.

public float getSueldo() {


return sueldo;

53.
54.
55.

}
public void setSueldo(float sueldo) {
this.sueldo = sueldo;

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 159


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

56.
}
57. }/* Definicion de la clase Empleado termina aqui */
58.
59. /*Definicion de la clase SerializableEjemplo comienza aqui*/
60. public class SerializableEjemplo {
61.
/* Metodo main comienza aqui */
62.
63.
64.

public static void main(String[] args) {


try {
int empCodigo;

65.
66.

String empNombre;
float empSueldo;

67.
68.
69.

// Crear instancia de BufferedReader


BufferedReader br;

70.
71.
72.

br = new BufferedReader(
new InputStreamReader(System.in)
);

73.
74.
75.

// Obtener detalles del empleado del usuario


System.out.println(

76.
77.
78.

"Ingrese los datos del Empleado:");


System.out.print("Codigo: ");
empCodigo = Integer.parseInt(br.readLine());

79.
80.
81.

System.out.print("Nombre: ");
empNombre = br.readLine().trim();
System.out.print("Salario: ");

82.
83.
84.

empSueldo = Float.parseFloat(br.readLine());

85.
86.
87.

Empleado emp1;
emp1 = new Empleado(
empCodigo,

88.
89.

empNombre,
empSueldo

90.
91.
92.

// Crear una instancia de clase Empleado

);
// Crear una instancia de FileOutputStream

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 160

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

93.
94.
95.

Core Java

FileOutputStream fos;
fos = new FileOutputStream(
"SerializadoEmpleado.txt

96.
97.
98.

");
// Crear una instancia de ObjectOutputStream

99.
100.
101.

ObjectOutputStream oos;
oos = new ObjectOutputStream(fos);

102.
103.

// Serializar detalles del empleado


oos.writeObject(emp1);

104.
105.
106.

System.out.println(
"\nLos datos del Empleado fueron " +
"serializados en SerializadoEmpleado.txt");

107.
108.
109.

// Cerrar ObjectOutputStream
oos.flush();

110.
111.
112.

oos.close();
} catch (NumberFormatException e) {
System.out.println("Valor invalido");

113.
114.
115.

System.exit(0);
} catch (Exception e) {
System.out.println(

116.
117.
118.

"Exception durante la serializacion: " +


e);
System.exit(0);

119.
120.
121.

122.
123.
124.

try {
// Crear una referencia de la clase Empleado
Empleado emp2;

125.
126.

// Crear una instancia de FileInputStream

127.
128.
129.

FileInputStream fis;
fis = new FileInputStream(
"SerializadoEmpleado.txt"

// Ahora deserealizar detalles de empleado

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 161


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

130.
131.
132.

Gua del Estudiante

);
// Crear una instancia de ObjectInputStream

133.
134.
135.

ObjectInputStream ois;
ois = new ObjectInputStream(fis);

136.
137.
138.

// Leer detalles de empleado


emp2 = (Empleado) ois.readObject();

139.
140.

// Cerrar ObjectInputStream
ois.close();

141.
142.
143.

/* Mostrar detalle del empleado


en la salida estandar */

144.
145.
146.

System.out.println(
"\nEmpleado deserealizado desde " +
"SerializadoEmpleado.txt\n" +

147.
148.
149.

emp2);
} catch (FileNotFoundException e) {
System.out.println(

150.
151.
152.

"Archivo no encontrado");
System.exit(0);
} catch (Exception e) {

153.
154.
155.

System.out.println(
"Exception durante la deserializacion: " + e);
System.exit(0);

156.
}
157.
}/* Metodo main termina aqui */
158. }/*Definicion de la clase SerializableEjemplo termina aqui*/
El cdigo Java termina aqu
La clase Empleado es inicializada con los datos introducidos por el usuario. La clase
SerializableEjemplo escribe los datos al archivo SerializadoEmpleado.txt
usando ObjectOutputStream. El programa lee los contenidos de este archivo usando
ObjectInputStream, y los imprime en la salida estndar.
El contenido del SerializadoEmpleado.txt es el siguiente:

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 162

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

La salida del programa es la siguiente:


Ingrese los datos del Empleado:
Codigo: 123
Nombre: Alvaro
Salario: 100000
Los datos del Empleado fueron serializados en
SerializadoEmpleado.txt
Empleado deserealizado desde SerializadoEmpleado.txt
***Datos del empleado***
Codigo: 123
Nombre: Alvaro
Sueldo: 100000.0
Fin del Ejemplo 3.3
Considere el Ejemplo 3.4.
Ejemplo 3.4
El siguiente ejemplo muestra como ObjectOutputStream y ObjectInputStream se
pueden usar en una clase que implementa la interfaz java.io.Externalizable
para almacenar y recuperar sus campos.
El cdigo Java comienza aqu
1.
2.
3.

import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;

4.
5.

import java.io.IOException;
import java.io.ObjectInput;

6.
7.
8.

import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

9.
10. /*Definicion de la clase Brazil comienza aqui*/
11. class Brazil implements Externalizable {
12.
13.
14.

/* Constructor Brazil comienza aqui */


public Brazil() {
System.out.println("Brazil Constructor");

15.
16.
17.

} /* Constructor Brazil termina aqui */


/* Metodo writeExternal comienza aqui */

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 163


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

18.
19.
20.

public void writeExternal(ObjectOutput out)


throws IOException {

21.
22.
23.

System.out.println("Brazil.writeExternal");
} /* Metodo writeExternal termina aqui */

24.
25.
26.

/* Metodo readExternal comienza aqui */


public void readExternal(ObjectInput in)
throws IOException,

27.
28.

ClassNotFoundException {

29.
System.out.println("Brazil.readExternal");
30.
} /* Metodo readExternal termina aqui */
31. }/* Definicion de la clase Brazil termina aqui */
32.
33. /* Definicion de la clase comienza aqui */
34. public class FutbolExternalizableEjemplo {
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.

/* Metodo main comienza aqui */


public static void main(String[] args) {
System.out.println(
"Construyendo instancia de Brazil");
Brazil objBrazil = new Brazil();
try {
ObjectOutputStream oos;
oos = new ObjectOutputStream(
new FileOutputStream("Futbol.txt")
);
System.out.println("Guardando objteo:");

47.
48.
49.

oos.writeObject(objBrazil);
oos.close();

50.
51.

// Ahora regreselos:
ObjectInputStream entrada;

52.
53.
54.

entrada = new ObjectInputStream(


new FileInputStream(
"Futbol.txt"

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 164

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

55.
56.
57.

Core Java

)
);

58.
59.
60.

System.out.println("Recuperando objeto:");
objBrazil = (Brazil) entrada.readObject();
} catch (IOException e) {

61.
62.
63.

System.out.println(e);
} catch (ClassNotFoundException e) {
System.out.println(e);

64.
65.

} catch (Exception e) {
e.printStackTrace();

66.
}
67.
}/* Metodo main termina aqui */
68. }/* Definicion de la clase termina aqui */
El cdigo Java termina aqu
En este programa, se crea el objeto Brazil. Este objeto es serializado
persistentemente y escrito en el archivo Futbol.txt. El contenido de Futbol.txt es
el siguiente:

El programa produce la siguiente salida:


Construyendo instancia de Brazil
Brazil Constructor
Guardando objteo:
Brazil.writeExternal
Recuperando objeto:
Brazil Constructor
Brazil.readExternal
Fin del Ejemplo 3.4

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 165


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Resumen
Ahora que ha completado esta unidad, usted debe ser capaz de:

Explicar la serializacin de objetos.

Explicar la interfaz Serializable.

Explicar la interfaz Externalizable.

Explicar la clase ObjectOutputStream.

Explicar la clase ObjectInputStream.

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 166

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Unidad 3: Examen de Autoevaluacin


1) La serializacin de objetos se usa en:
a) Invocacin de Mtodos Remotos (Remote Method Invocation RMI)
b) Persistencia Ligera
c) Ambas anteriores
d) Ninguna de las anteriores
2) Cul de las siguientes es una interfaz vaca?
a) ObjectOutput
b) ObjectInput
c) Externalizable
d) Serializable
3) Si una superclase de una clase no es serializable, entonces la subclase puede
asumir la responsabilidad de serializar los campos accesibles de la superclase y
restaurarlos.
a) Verdadero
b) Falso
4) Cul de los siguientes modificadores hace que los campos sean no serializables?
a) transient
b) static
c) Serializable
d) Externalizable
5) Qu ocurre cuando se encuentra un objeto no serializable mientras se recorre
una jerarqua de objetos en la serializacin?
a) Se lanza NotSerializableException
b) Su superclase serializable puede encargarse de serializar sus campos
c) Su subclase serializable puede encargarse de serializar sus campos
d) Ninguna de las anteriores
6) El mtodo defaultReadObject usa el mecanismo por defecto para restaurar los
campos no estticos y no transient.
a) Verdadero
b) Falso

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 167


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

7) Para tener un objeto sustituto mientras se escribe a un ObjectOutputStream se


usa el mtodo writeReplace().
a) Verdadero
b) Falso
8) Para tener un objeto sustituto mientras se lee de un ObjectInputStream, se
aplica el mtodo readReplace().
a) Verdadero
b) Falso
9) Cul de las siguientes interfaces permite tener coordinacin con la superclase de
una clase durante la serializacin y deserializacin?
a) Serializable
b) Externalizable
c) ObjectOutput y ObjectInput
d) DataOutput y DataInput
10) Cules de los siguientes mtodos se implementan para proporcionar el control
completo del formato de serializacin, as como de los estados del objeto y los
objetos de su superclase que van a ser serializados?
a) writeExternal y readExternal
b) writeObject y readObject
c) writeReplace y readResolve
d) Ninguna de las anteriores

Unidad 3: Serializacin de Objetos

Libro 2: Core Java 168

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Respuestas a la Unidad 3: Examen de Autoevaluacin


1) c
2) d
3) b (la super clase debe tener un constructor sin argumentos accesible)
4) a y b
5) a y c
6) a
7) a
8) b
9) b
10) a

Libro 2: Core Java

Unidad 3: Serializacin de Objetos 169


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

Unidad 4: Laboratorio de Serializacin


de Objetos
Objetivos del Aprendizaje
Al final de esta unidad, usted ser capaz de:

Trabajar con la serializacin de objetos en Java.

Usar las clases ObjectInputStream y ObjectOutputStream.

Unidad 4: Laboratorio de Serializacin de Objetos

Libro 2: Core Java 170

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Gua del Estudiante

Core Java

Ejercicios de Laboratorio
1) Escriba un programa en Java para guardar la hora del sistema en un archivo.
Recomendaciones tiles:

Escriba una clase Serializable llamada MiClase.

Declare una variable string y defina un mtodo para recuperar la variable string.
El valor de la variable string puede ser asignado usando el constructor de
MiClase.

Escriba una clase llamada HoraDelSistema.

Cree un objeto File representado al archivo Hora.txt.

Abra un FileOutputStream envuelto con un ObjectOutputStream en el


objeto File.

Cree una instancia de la clase Date y extraiga los detalles de la hora e


imprmela en la salida estndar.

Escriba los detalles de la hora en Hora.txt con ObjectOutputStream.

Abra un FileInputStream envuelto con un ObjectInputStream sobre


Hora.txt.

Lea los contenidos de Hora.txt e imprmalos en la salida estndar.

2) La mayora conoce el juego del tenis. Para aquellos que no conocen nada de tenis,
se dar una breve introduccin al juego. El juego se juega usualmente entre dos o
cuatro jugadores. Un match (partido) entre dos jugadores se llama un match sencillo y
entre cuatro jugadores, dos en cada equipo, se llama match doble. Los matches se
clasifican segn el gnero, de forma que se tienen: los matches sencillos y dobles de
hombres, y los matches sencillos y dobles de mujeres, tambin hay matches dobles
mixtos, que involucran a un hombre y una mujer por equipo. Para este ejercicio, se
limitarn las reglas para match sencillo de tenis. El juego del tenis es nico en varios
aspectos, en trminos de puntos, jugadores sirviendo, etc. De nuevo en el contexto de
este ejercicio, nos limitaremos a las reglas sobre los puntos en un match.
El sistema de puntaje en un match sencillo de tenis es diferente a otros juegos como el
ftbol, bsquetbol, voleibol, etc. Un match de tenis consiste de 3 o 5 sets. El jugador
que gane los primeros 6 juegos es declarado ganador del set siempre y cuando el otro
jugador no haya ganado 5 juegos. Si los jugadores estn empatados en los 6 juegos,
se introduce el tiebreak (empate). En un tiebreak, el jugador que gane los primeros
siete puntos gana el juego y el set. Sin embargo, tiene que liderar a su rival por dos
puntos. En el caso de que dos jugadores estn empatados a 6 puntos en el tiebreak, el
juego se extiende hasta que el margen de dos puntos sea alcanzado por alguno de los
jugadores.
La divisin de los puntos en un juego tambin es diferente de otros juegos. El primer
punto que un jugador gana en un juego le otorga 15 puntos. El prximo punto lleva su
puntaje a 30. El tercer punto lleva su puntaje a 40 y el prximo punto gana el juego. En
Libro 2: Core Java

Unidad 4: Laboratorio de Serializacin de Objetos 171


Copyright IBM Corp. 2007
Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

Core Java

Gua del Estudiante

caso de que los jugadores estn empatados 40-40, el juego va a deuce, donde el
jugador que gane dos puntos consecutivos gana. Cuando un jugador gana el primer
punto del deuce, se dice que tiene un Advantage (ventaja) sobre su oponente. Si gana
el segundo punto, gana el juego. Si no, si su oponente lo gana, el juego vuelve a
Deuce.
Todos los eventos de tenis femenino y dobles mixtos tienen 3 sets. Los eventos de los
hombres tienen 3 sets o 5 sets. Con esta explicacin acerca del tenis, se va a resolver
el ejercicio.
La copa Grandmaster es un evento anual entre Estados Unidos y Rusia. Escriba un
programa en Java que mantenga el tablero de puntajes de los matches sencillos entre
los jugadores de los dos pases. El programa debe almacenar el tablero de puntajes al
final del juego. La clase PuntajeTablero tiene dos instancias de la clase Equipo. La
primera instancia tendr el puntaje de USA y la segunda, el de Rusia. La clase Equipo
tiene una subclase, MaestroDelTenis. La clase MaestroDelTenis tiene los
nombres de todos los jugadores en el equipo, el nmero de sets ganados por cada
jugador y el nmero de matches ganados por el jugador. La clase tambin tendr
mtodos para actualizar esta informacin. La clase Tenis actualiza al
PuntajeTablero y almacena el PuntajeTablero, al final del da de juego en un
archivo.
Recomendaciones tiles:

Escriba una clase Serializable llamada Equipo que tenga una subclase
Serializable llamada MaestroDelTenis.

La clase MaestroDelTenis tiene el nombre del jugador, el nmero de sets


ganados y si el jugador ha ganado el match.

La clase Equipo tiene un mtodo actualizarEquipo() que actualiza la


informacin del equipo especificada a travs de parmetros.

Escriba una clase ScoreBoard que tenga el puntaje de ambos USA y Rusia a
travs de los dos objetos Team.

La clase PuntajeTablero tiene un mtodo actualizarPuntajeTablero()


que permite actualizar el objeto equipo especificado (como parmetro).
Tambin tendr el mtodo toString() que permite obtener los detalles de un
equipo en particular.

PuntajeTablero se serializa usando ObjectOutputStream y se guarda en


un archivo llamado puntaje.txt.

Los
contenidos
de
puntaje.txt
son
deserializados
ObjectInputStream e impresos en la salida estndar.

Unidad 4: Laboratorio de Serializacin de Objetos

usando

Libro 2: Core Java 172

Copyright IBM Corp. 2007


Los materiales del curso no pueden ser reproducidos total o
parcialmente sin el previo permiso escrito de IBM.

También podría gustarte