Entrada y Salida con Java
Programacin Orientada a Objetos Facultad de Informtica
Juan Pavn Mestras Dep. Ingeniera del Software e Inteligencia Artificial Universidad Complutense Madrid
E/S con flujos (streams)
En Java se define la abstraccin de stream (flujo) para tratar la comunicacin de informacin entre el programa y el exterior
Entre una fuente y un destino fluye una secuencia de datos
Los flujos actan como interfaz con el dispositivo o clase asociada
Operacin independiente del tipo de datos y del dispositivo Mayor flexibilidad (p.e. redireccin, combinacin) Diversidad de dispositivos (fichero, pantalla, teclado, red, ) Diversidad de formas de comunicacin
Modo de acceso: secuencial, aleatorio Informacin intercambiada: binaria, caracteres, lneas
flujo (stream)
Fuente
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
...
dato
dato
Destino
Entrada/Salida con Java
Flujos estndar
Como en Unix:
Entrada estndar - habitualmente el teclado Salida estndar - habitualmente la consola Salida de error - habitualmente la consola
En Java se accede a la E/S estndar a travs de campos estticos de la clase [Link]
[Link] implementa la entrada estndar [Link] implementa la salida estndar [Link] implementa la salida de error
Dispositivo de entrada
([Link])
Flujo entrada
Flujo salida
Datos
Programa
Datos
([Link])
Dispositivo de salida
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
Flujos estndar
[Link]
Instancia de la clase InputStream: flujo de bytes de entrada Metodos
read() permite leer un byte de la entrada como entero skip(n ) ignora n bytes de la entrada available() nmero de bytes disponibles para leer en la entrada
[Link]
Instancia de la clase PrintStream: flujo de bytes de salida Metodos para impresin de datos
print(), println() flush() vaca el buffer de salida escribiendo su contenido
[Link]
Funcionamiento similar a [Link] Se utiliza para enviar mensajes de error (por ejemplo a un fichero de log o a la consola)
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
Ejemplo - uso flujos estndar
import [Link].*; class LecturaDeLinea { public static void main( String args[] ) throws IOException { int c; int contador = 0; // se lee hasta encontrar el fin de lnea while( (c = [Link]() ) != '\n' ) { contador++;
[Link]( (char) c );
}
[Link](); // Se escribe el fin de lnea [Link]( "Contados "+ contador +" bytes en total." );
} }
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
Utilizacin de los flujos
Los flujos se implementan en las clases del paquete [Link] Esencialmente todos funcionan igual, independientemente de la fuente de datos
Clases [Link] y [Link]
int read() int read(char buffer[]) int read(char buffer[], int offset, int length) int write(int aCharacter) int write(char buffer[]) int write(char buffer[], int offset, int length)
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
Utilizacin de los flujos
Lectura
1.
Abrir un flujo a una fuente de datos (creacin del objeto stream)
Teclado Fichero Socket remoto Leer datos
2. 3.
Mientras existan datos disponibles Cerrar el flujo (mtodo close) Abrir un flujo a una fuente de datos (creacin del objeto stream)
Pantalla Fichero Socket local
Escritura
1.
2. 3.
Mientras existan datos disponibles Cerrar el flujo (mtodo close)
Escribir datos
Nota: para los flujos estndar ya se encarga el sistema de abrirlos y cerrarlos Un fallo en cualquier punto produce la excepcin IOException
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
Entrada de texto desde un fichero
try { BufferedReader reader = new BufferedReader(new FileReader(nombrefichero")); String linea = [Link](); while(linea != null) { // procesar el texto de la lnea linea = [Link](); } [Link](); } catch(FileNotFoundException e) { // no se encontr el fichero } catch(IOException e) { // algo fue mal al leer o cerrar el fichero }
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
Clasificacin de flujos
Representacin de la informacin
Flujos de bytes: clases InputStream y OutputStream Flujos de caracteres: clases Reader y Writer
Se puede pasar de un flujo de bytes a uno de caracteres con InputStreamReader y OutputStreamWriter
Propsito
Entrada: InputStream, Reader Salida: OutputStream, Writer Lectura/Escritura: RandomAccessFile Transformacin de los datos
Realizan algn tipo de procesamiento sobre los datos (p.e. buffering, conversiones, filtrados): BuffuredReader, BufferedWriter
Acceso
Secuencial Aleatorio - (RandomAccessFile)
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
Jerarqua de flujos de bytes
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
10
Jerarqua de flujos de caracteres
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
11
Entrada de caracteres
InputStreamReader
Lee bytes de un flujo InputStream y los convierte en caracteres Unicode Mtodos de utilidad
read() lee un nico caracter ready() indica cuando est listo el flujo para lectura
BufferedReader
Entrada mediante bfer, mejora el rendimiento Mtodo de utilidad
readLine() lectura de una lnea como cadena InputStreamReader entrada = new InputStreamReader([Link]); BufferedReader teclado = new BufferedReader (entrada); String cadena = [Link]();
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
12
Combinacin de flujos
Los flujos se pueden combinar para obtener la funcionalidad deseada
InputStream
InputStreamReader
BufferedReader
Programa
Lee bytes Lee bytes y los pasa a caracteres Unicode Utiliza un bfer para mejorar eficiencia de lectura de carateres
Flujos de transformacin de datos
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
13
Ejemplo - combinacin de flujos
import [Link].*; public class Eco { public static void main (String[] args) { BufferedReader entradaEstandar = new BufferedReader (new InputStreamReader([Link])); String mensaje; [Link] ("Introducir una lnea de texto:"); mensaje = [Link](); [Link] ("Introducido: \"" + mensaje + "\""); } }
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
14
La clase Teclado
import [Link].*; public class Teclado { /** variable de clase asignada a la entrada estndar del sistema */ public static BufferedReader entrada = new BufferedReader(new InputStreamReader([Link])); /** lee una cadena desde la entrada estndar * @return cadena de tipo String */ public static String leerString() { String cadena=""; try { cadena = new String([Link]()); }catch (IOException e) { [Link]("Error de E/S"); } return cadena; } // la clase Teclado continua
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
15
La clase Teclado
// ...continuacin de la clase teclado /** lee un numero entero desde la entrada estandar * @return numero entero de tipo int */ public static int leerInt() { int entero = 0; boolean error = false; do { try { error = false; entero = [Link]([Link]()).intValue(); }catch (NumberFormatException e1) { error = true; [Link]("Error en el formato del numero, intentelo de nuevo."); }catch (IOException e) { [Link]("Error de E/S");} } while (error); return entero; } } // final de la clase Teclado
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
16
Flujos de bytes especiales
File streams
Para escribir y leer datos en ficheros
Object streams
Para escribir y leer objetos Implementa lo que se denomina serializacin de objetos (object serialization)
Es posible guardar un objeto con una representacin de bytes
Filter streams
Permiten filtrar datos mientras se escriben o leen
Se construyen sobre otro flujo
Permiten manipular tipos de datos primitivos Implementan las interfaces DataInput y DataOutput y pueden heredar de las clases FilterInputStream y FilterOutputStream
El mejor ejemplo son las clases DataInputStream y DataOutputStream para leer y escribir datos de tipos bsicos
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
17
Uso de filter streams
Para leer tipos de datos primitivos
Se puede utilizar un DataInputStream
FileInputStream ficheroEntrada = new FileInputStream([Link]"); DataInputStream entrada = new DataInputStream(ficheroEntrada); double precio= entrada .readDouble(); [Link]();
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
18
Uso de filter streams
Para escribir tipos de datos primitivos
Se puede utilizar un DataOutputStream
FileOutputStream ficheroSalida = new FileInputStream([Link]"); DataOutputStream salida = new DataInputStream(ficheroSalida); [Link](234.56); [Link](); [Link]();
Fuerza la escritura de los datos
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
19
Ficheros de texto
FileReader
Para leer de ficheros de texto Hereda de InputStreamReader, que hereda de Reader Constructor: FileReader(String nombreFichero)
FileWriter
Para escribir en ficheros de texto Hereda de OutputStreamReader, que hereda de Writer Constructores
FileWriter(String nombreFichero) -- reescribe FileWriter(String nombreFichero, boolean aadirFinal) -- aade
PrintWriter
Implementa un flujo de salida de caracteres Mtodos de utilidad
print(), println(), close()
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
20
Ejemplo Ficheros de texto
import [Link].*; public class FicheroTexto { public static void main(String args[]) { try { // escritura de datos PrintWriter salida = new PrintWriter( new BufferedWriter(new FileWriter("[Link]")) ); [Link](Este es un ejemplo de escritura y lectura de datos"); [Link](en un fichero."); [Link](); // lectura de datos BufferedReader entrada =new BufferedReader(new FileReader("[Link]")); String s, s2 = new String(); while((s = [Link]())!= null) s2 += s + "\n"; [Link]("Texto leido:" + "\n" + s2); [Link](); } catch ([Link] e) { [Link](); } } }
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
21
Ficheros
Clase File
Constructores
File(String ruta) File(String ruta, String nombre) File(File directorio, String nombre)
Mtodos
canRead() comprueba si el fichero se puede leer canWrite() comprueba siel fichero se puede escribir delete() borra dicho fichero getPath() devuelve la ruta del fichero mkdir() crea un directorio con la ruta del objeto que lo recibe isDirectory() comprueba si dicho fichero es un directorio
Constructores de otras clases
FileReader(File fichero) FileWriter(File fichero)
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
22
Ejemplo: Copia de ficheros
import [Link].*; public class CopiaFicheros { public static void main(String[] args) throws IOException { File ficheroEntrada = new File("[Link]"); File ficheroSalida = new File("[Link]"); FileReader entrada = new FileReader(ficheroEntrada); FileWriter salida = new FileWriter(ficheroSalida); int dato; while ( (dato = [Link]()) != -1 ) [Link](dato); [Link](); [Link](); } } Es importante cerrar los flujos
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
23
Serializacin de objetos
Serializar es almacenar objetos directamente en como una secuencia de bytes, por ejemplo en un fichero
Sirve para guardar objetos y reconstruirlos posteriormente (persistencia)
Flujos
Clase ObjectOuputStream
Mtodo - writeObject() Ejemplo: [Link] (objetoClase);
Clase ObjectInputStream
Mtodo - readObject() Ejemplo: objetoClase = (Clase) [Link]();
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
24
Interfaz Serializable
Cualquier clase que desee poder serializar sus objetos debe implementar la interfaz Serializable
En esta implementacin el objeto define cmo debe almacenarse o recuperarse de un fichero con los mtodos
writeObject: responsable de escribir el estado del objeto en el flujo readObject: responsable de recuperar el estado del objeto desde el flujo
Si se trata de serializar un objeto que no lo implementa se obtiene la excepcin NotSerializableException public interface Serializable { private void writeObject([Link] out) throws IOException private void readObject([Link] in) throws IOException, ClassNotFoundException; }
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
25
Serializacin de objetos
Ejemplo: serializacin de un objeto que guarda un calendario
GregorianCalendar calendario = new GregorianCalendar(); ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("[Link]")); [Link](calendario); [Link](); public class [Link] extends [Link]{
public class [Link] extends [Link] implements [Link], [Link]{
Como Calendar implementa Serializable, GregorianCalendar tambin
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08 Entrada/Salida con Java
26
Deserializacin de objetos
Utilizando la clase ObjectInputStream
Hay que respetar el orden en el que se guardaron los elementos de estado del objeto para poder hacer un casting al tipo correcto
ObjectInputStream in = new ObjectInputStream (new FileInputStream("[Link]")); GregorianCalendar calendario = (GregorianCalendar)[Link](); [Link]();
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
27
Resumen
La E/S en Java sigue el mismo modelo que en Unix:
Abrir, usar, cerrar flujo Flujos estndar: [Link], [Link] y [Link]
Dos tipos de clases de E/S:
Readers y Writers para texto
Basados en el tipo char
Streams (InputStream y OutputStream) para datos binarios
Basados en el tipo byte
Los flujos de E/S se pueden combinar para facilitar su uso La E/S suele ser propensa a errores
Implica interaccin con el entorno exterior Excepcin IOException
Juan Pavn Mestras Facultad de Informtica UCM, 2007-08
Entrada/Salida con Java
28