Clase de Streams

Anuncio
Algoritmos y Estructura de Datos I
Entrada/Salida. Streams.
Melanie Sclar
May 23, 2014
Melanie Sclar
Algoritmos y Estructura de Datos I
¿Qué es un stream?
Stream en inglés significa ”corriente” o ”torrente”. En
nuestro caso, será una corriente de datos que según el caso
puede representar una fuente de entrada o un destino de
salida de datos del programa.
Hay dos tipos principales de streams:
Los input streams
Los output streams
Melanie Sclar
Algoritmos y Estructura de Datos I
Tipos de streams
Un input stream es aquel que se utiliza para leer datos desde
una fuente.
Un output stream es aquel que se utiliza para escribir datos
hacia un destino.
Las clases básicas de input y output streams son
InputStream y OutputStream respectivamente.
Estas clases son muy básicas pues leen/escriben de a un byte.
Por este motivo no serán muy prácticas, pero envolviéndolas
en otras clases sı́ podrán serlo (ya lo veremos).
Melanie Sclar
Algoritmos y Estructura de Datos I
Las versiones buffered de los streams
Un buffer es un espacio de memoria donde se almacenan
datos.
Como los streams recién nombrados leen de a un byte, cada
byte que se desee leer representará un nuevo llamado al
sistema para pedirle que lea/imprima datos.
Esto es muy costoso si vamos a leer/escribir numerosas veces.
Melanie Sclar
Algoritmos y Estructura de Datos I
Para poder leer y escribir más ágilmente se crearon las clases
BufferedInputStream y BufferedOutputStream.
La ventaja de usar buffering es que si se va a leer/escribir
varias veces, se guarda en memoria varios pedidos y se
mandan todos de una sola vez.
Esto permite que la lectura/escritura (que ya de por sı́ es
lenta) se agilice pues se baja la cantidad de pedidos al sistema.
Lo interesante del buffering es que nosotros no vemos ninguna
diferencia: todo esto se manejará automáticamente.
Melanie Sclar
Algoritmos y Estructura de Datos I
Los 3 streams estándar: System.in, System.out,
System.err
Los 3 streams estándar son el de entrada estándar
(System.in), el de salida estándar (System.out) y el de
error estándar (System.err).
La entrada estándar es la que estuvieron usando hasta ahora:
se leen los datos de entrada desde la consola. System.in es
un InputStream para leer desde la entrada estándar.
La salida estándar es la salida por pantalla. System.out es
un OutputStream para escribir en la salida estándar.
El error estándar es por donde se imprimen todas las
excepciones del programa, junto con lo que nosotros
queramos agregarle (errores que nosotros deseamos que se
impriman por allı́). Se verá por la misma consola de la salida
estándar (salvo que la redirijamos).
Melanie Sclar
Algoritmos y Estructura de Datos I
Readers y Writers
Ya vimos los streams más básicos, que dijimos que
leen/escriben de a bytes. También observamos que esto es
impráctico, y que nos gustarı́a tener alguna manera de leer de
a chars/strings.
Para lograr esto, utilizaremos los readers y los writers.
A los readers se les pasará un InputStream (que lee de a
bytes) y lo “envolverá”, de manera tal que ahora se pueda leer
de a chars/strings.
Análogamente, a un writer se le pasará un OutputStream y
éste lo envolverá para que pueda escribir de a chars/strings.
InputStreamReader inputStreamReader
= new I n p u t S t r e a m R e a d e r ( System . i n ) ;
Melanie Sclar
Algoritmos y Estructura de Datos I
Buffered Readers y Writers
Al igual que con los streams antes vistos, también existe la
versión buffered de los readers y writers.
BufferedReader y BufferedWriter tomarán un
reader/writer y lo envolverán para que tenga capacidad de
buffering y ası́ ganar eficiencia.
BufferedReader bufferedReader =
new B u f f e r e d R e a d e r ( i n p u t S t r e a m R e a d e r ) ;
Melanie Sclar
Algoritmos y Estructura de Datos I
Leer/Escribir de un archivo con Readers y Writers
FileWriter y FileReader son clases que permitirán
leer/escribir desde un archivo con la comodidad de hacerlo de
a char/string. Para hacerlo, se tomará por parámetro el path
del archivo, devolviéndose un reader o writer.
F i l e R e a d e r f i l e R e a d e r = new F i l e R e a d e r ( ” a r c h i v o . i n ” ) ;
Melanie Sclar
Algoritmos y Estructura de Datos I
Ejemplo de uso de reader y writer
BufferedReader reader =
new B u f f e r e d R e a d e r ( new I n p u t S t r e a m R e a d e r ( System . i n ) ) ;
BufferedWriter writer =
new B u f f e r e d W r i t e r ( new F i l e W r i t e r ( ” a r c h i v o . o u t ” ) ) ;
r e a d e r . r e a d L i n e ( ) ; // Lee una l i n e a
// l o puedo h a c e r p o r q u e ” r e a d e r ” e s B u f f e r e d R e a d e r
w r i t e r . w r i t e ( ” s o y un s t r i n g ” ) ; // E s c r i b e un s t r i n g
¿Cómo escribo una lı́nea?
Melanie Sclar
Algoritmos y Estructura de Datos I
Ejemplo de uso de reader y writer
BufferedReader reader =
new B u f f e r e d R e a d e r ( new I n p u t S t r e a m R e a d e r ( System . i n ) ) ;
BufferedWriter writer =
new B u f f e r e d W r i t e r ( new F i l e W r i t e r ( ” a r c h i v o . o u t ” ) ) ;
r e a d e r . r e a d L i n e ( ) ; // Lee una l i n e a
// l o puedo h a c e r p o r q u e ” r e a d e r ” e s B u f f e r e d R e a d e r
w r i t e r . w r i t e ( ” s o y un s t r i n g ” ) ; // E s c r i b e un s t r i n g
¿Cómo escribo una lı́nea? Agrego \n al final del string, que es el
caracter de fin de lı́nea.
w r i t e r . w r i t e ( m i S t r i n g+” \n” ) ;
Melanie Sclar
Algoritmos y Estructura de Datos I
Ejemplo de uso de reader y writer
BufferedReader reader =
new B u f f e r e d R e a d e r ( new I n p u t S t r e a m R e a d e r ( System . i n ) ) ;
BufferedWriter writer =
new B u f f e r e d W r i t e r ( new F i l e W r i t e r ( ” a r c h i v o . o u t ” ) ) ;
r e a d e r . r e a d L i n e ( ) ; // Lee una l i n e a
// l o puedo h a c e r p o r q u e ” r e a d e r ” e s B u f f e r e d R e a d e r
w r i t e r . w r i t e ( ” s o y un s t r i n g ” ) ; // E s c r i b e un s t r i n g
¿Cómo escribo una lı́nea? Agrego \n al final del string, que es el
caracter de fin de lı́nea.
w r i t e r . w r i t e ( m i S t r i n g+” \n” ) ;
¿Cómo escribo un int?
Melanie Sclar
Algoritmos y Estructura de Datos I
Ejemplo de uso de reader y writer
BufferedReader reader =
new B u f f e r e d R e a d e r ( new I n p u t S t r e a m R e a d e r ( System . i n ) ) ;
BufferedWriter writer =
new B u f f e r e d W r i t e r ( new F i l e W r i t e r ( ” a r c h i v o . o u t ” ) ) ;
r e a d e r . r e a d L i n e ( ) ; // Lee una l i n e a
// l o puedo h a c e r p o r q u e ” r e a d e r ” e s B u f f e r e d R e a d e r
w r i t e r . w r i t e ( ” s o y un s t r i n g ” ) ; // E s c r i b e un s t r i n g
¿Cómo escribo una lı́nea? Agrego \n al final del string, que es el
caracter de fin de lı́nea.
w r i t e r . w r i t e ( m i S t r i n g+” \n” ) ;
¿Cómo escribo un int? Como estos writers sólo escriben de a
strings, tengo que pasar el int a string (con el método valueOf) y
luego imprimir.
w r i t e r . write ( String . valueOf (3421343))
Melanie Sclar
Algoritmos y Estructura de Datos I
PrintWriter
Como un writer sólo imprime de a strings o chars, si lo que
deseamos imprimir es de otro tipo de dato deberemos pasarlo
previamente a string (como hicimos con los enteros, llamando
al método valueOf).
Dado que esto es sumamente impráctico, podemos usar la
clase PrintWriter que toma un writer y provee un método
de impresión más cómodo (.print() para numerosos tipos de
datos).
PrintWriter
printWriter
printWriter
printWriter
p r i n t W r i t e r = new P r i n t W r i t e r ( w r i t e r ) ;
. p r i n t l n ( ” E s t o i m p r i m e una l i n e a de t e x t o ” ) ;
. print (2323);
. p r i n t ( ”Ya no f a l t a n t a n t a s d i a p o s ! ” ) ;
Melanie Sclar
Algoritmos y Estructura de Datos I
Scanner
Scanner es una clase que facilita la lectura de datos.
En cada lectura lee todos los caracteres que hay entre dos
espacios en blanco, y según con qué método se lo haya
llamado, los traduce automáticamente al tipo de dato
especificado.
S c a n n e r s c a n n e r = new S c a n n e r ( new B u f f e r e d R e a d e r ( new I n p u t S t r e a m R e a d e r ( System . i n ) ) ) ;
S t r i n g s = s c a n n e r . n e x t ( ) ; // I n g r e s a e l s i g u i e n t e s t r i n g
i n t j = s c a n n e r . n e x t I n t ( ) ; // I n g r e s a e l s i g u i e n t e i n t
d o u b l e z z = s c a n n e r . n e x t D o u b l e ( ) ; // I n g r e s a un d o u b l e
Melanie Sclar
Algoritmos y Estructura de Datos I
¿Cómo cerramos un stream?
Hasta ahora vimos cómo abrir un stream para poder
leer/escribir de donde deseáramos. Es intuitivo suponer que si
abrimos algo, cuando lo terminemos de usar lo tenemos que
cerrar.
Para eso existe el método ss.close(), si ss es el stream que
deseamos cerrar.
Es importantı́simo cerrar los streams luego de usarlos, y
asegurarse de cerrarlos no importa qué pase en el programa.
Veamos cómo.
Melanie Sclar
Algoritmos y Estructura de Datos I
¿Cómo cerramos un stream? (2)
Supongamos que tenemos el siguiente código:
p ub l ic s t a t i c void ejemplo () {
F i l e W r i t e r e n t r a d a = new F i l e W r i t e r ( ” a r c h i v o . i n ” ) ;
...
i n t x = 1000 / ( 1 0 % 2 ) ;
...
entrada . close ( ) ;
}
¿Este código termina bien? ¿Se cierra el stream?
Melanie Sclar
Algoritmos y Estructura de Datos I
¿Cómo cerramos un stream? (3)
¡No!, porque al intentar ejecutar la lı́nea donde definimos x se
lanza una excepción de división por cero y termina el
programa.
En ese caso, no se llega a ejecutar la lı́nea del close, por lo
que nunca cerramos el stream.
Esto está mal, pues puede traer como consecuencia que no se
termine de imprimir todo lo que se debı́a haber impreso.
Melanie Sclar
Algoritmos y Estructura de Datos I
¿Cómo cerramos un stream? (4)
p u b l i c s t a t i c v o i d ejemploDeUsoDeUnStream ( ) {
FileWriter entrada = n u l l ;
try {
e n t r a d a = new F i l e W r i t e r ( ” a r c h i v o . i n ” ) ;
...
} finally {
// E s t a s e c c i o n de c o d i g o s e e j e c u t a S I O S I
i f ( e n t r a d a != n u l l ) {
try {
entrada . close ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( );
}
}
}
}
Usando try/finally, nos aseguramos que la sección de código del
finally se ejecute siempre, ya sea que haya terminado bien el código
del try o no.
Melanie Sclar
Algoritmos y Estructura de Datos I
Bibliografı́a
http://docs.oracle.com/javase/tutorial/essential/io/streams.html
Melanie Sclar
Algoritmos y Estructura de Datos I
Descargar