52
Departamento de Matemáticas y Computación Grado en Informática Programación de Bases de Datos OutputStream os = new OutputStream(); Java IO - Streams JDBC por Francisco J. García Izquierdo. Universidad de la Rioja. Departamento de Matemáticas y Computación. se encuentra bajo una Licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 Unported .

Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

  • Upload
    lamdieu

  • View
    229

  • Download
    2

Embed Size (px)

Citation preview

Page 2: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 2 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 3: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 3 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 4: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 4 © Francisco J. García Izquierdo

Vamos a utilizar Java como lenguaje de programación de la

asignatura

Una de las características intrínsecas de los sistemas distribuidos:

computadores conectados que se intercambian mensajes

Las conexiones de red en Java son tratadas como streams (como si

fuesen ficheros)

A través de esos streams se envían y reciben los mensajes (como

si grabásemos o leyésemos ficheros)

Además la información intercambiada entre los nodos estará, en

muchas ocasiones, almacenada en ficheros.

Es imprescindible un dominio de los APIs de entrada/salida de Java

Justificación

Page 5: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 5 © Francisco J. García Izquierdo

La E/S de Java se realiza a través de flujos (streams). Secuencia ordenada de bytes

Estos pueden ser de entrada (InputStream) o de salida (OutputStream).

Independizan a los objetos de origen/destino de los datos.

Las clases de E/S se encuentran en el paquete java.io.

Los métodos de OutputStream (y también de InputStream) lanzan la excepción IOException ante cualquier fallo relacionado con el intento de escritura o lectura

Streams

Page 6: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 6 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 7: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 7 © Francisco J. García Izquierdo

Clase abstracta de la que derivan los demás flujos de salida.

Fundamentalmente ofrece los siguientes servicios:

public abstract void write(int b) throws IOException

public void write(byte b[]) throws IOException

public void write(byte b[], int off, int len) throws IOException

public void flush() throws IOException

public void close() throws IOException

Como OutputStream es una clase abstracta. ¿Dónde se envía un byte que se escribe a través de un OutputStream?

Dependerá del tipo del stream.

Hay varias clases que derivan de OutputStream y redefinen el método write para darle una implementación distinta: FileOutputStream

ByteArrayOutputStream

PipedOutputStream

sun.net.TelnetOutputStream

La clase OutputStream

Page 8: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 8 © Francisco J. García Izquierdo

Page 9: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 9 © Francisco J. García Izquierdo

El FileOutputStream redefine el

método write para enviar el byte a un

fichero.

Véanse los constructores disponibles en la

ayuda de Java.

FileOutputStream

FileOutputStream f;

f = new FileOutputStream(“Datos.dat”);

for (int i = 0; i < 100; i++)

f.write(i);

f.close();

Page 10: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 10 © Francisco J. García Izquierdo

El ByteArrayOutputStream redefine el método write para enviar

el byte a un array dinámico (en memoria).

Añade los métodos:

public byte[] toByteArray()

public int size()

Ejemplo

ByteArrayOutputStream

ByteArrayOutputStream ba;

ba = new ByteArrayOutputStream();

for (int i = 0; i < 100; i++)

ba.write(i);

ba.close();

// Con “ba.toByteArray()” accedemos al array

// con los bytes escritos

Page 11: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 11 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 12: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 12 © Francisco J. García Izquierdo

Un filtro de salida es un OutputStream al cual se le

asocia en su constructor otro OutputStream (patrón

Decorator)

Los filtros reenvían toda la información que reciben a su OutputStream asociado, previa realización de algún

tipo de transformación en la misma.

De esta manera cada filtro añade una funcionalidad adicional al OutputStream que encapsula.

Se pueden encadenar varios filtros para obtener varias

funcionalidades combinadas.

FilterOutputStream

Page 13: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 13 © Francisco J. García Izquierdo

FileOutputStream ByteArrayOutputStream TelnetOutputStreamPipedOutputStream FilterOutputStream

BufferedOutputStreamPrintStreamDataOutputStreamGZIPOutputStream

OutputStream

+f lush:void

+write:void

+close:void

Page 14: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 14 © Francisco J. García Izquierdo

BufferedOutputStream

FileOutputStreamFileOutputStream

GZIPOutputStream

BufferedOutputStream

FileOutputStream

Composición de filtros

OutputStream out =

new FileOutputStream(

“f.txt”) ;

new CipherOutputStream(

)

new GZIPOutputStream(

)

CipherOutputStream CipherOutputStream

Page 15: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 15 © Francisco J. García Izquierdo

Los métodos de la clase OutputStream solo permiten enviar bytes.

Cualquier otro tipo deberán descomponerse en una secuencia de bytes antes de poder escribirse.

FileOutputStream out = new FileOutputStream(“datos.dat”);

int i;

out.write((i >>> 24) & 0xFF);

out.write((i >>> 16) & 0xFF);

out.write((i >>> 8) & 0xFF);

out.write((i >>> 0) & 0xFF);

// Idem para String, float, etc.

Filtro DataOutputStream

Page 16: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 16 © Francisco J. García Izquierdo

La clase DataOutputStream añade la funcionalidad de poder enviar todos los tipos primitivos directamente.

void writeBytes(String s) throws IOException

void writeBoolean(boolean v) throws IOException

void writeShort(int v) throws IOException

void writeChar(int v) throws IOException

void writeInt(int v) throws IOException

void writeLong(long v) throws IOException

void writeFloat(float v) throws IOException

void writeDouble(double v) throws IOException

void writeChars(String s) throws IOException

Filtro DataOutputStream

Page 17: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 17 © Francisco J. García Izquierdo

Filtro DataOutputStream

DataOutputStream dos;

dos = new DataOutputStream(new FileOutputStream(“A”));

dos.writeInt(i);

dos.writeDouble(3.14);

dos.writeChars(“Hola”);

dos.close(); // Se cierra también el socio

Page 18: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 18 © Francisco J. García Izquierdo

La clase PrintStream añade la funcionalidad de poder enviar

todos los tipos primitivos en formato texto.

Ofrece los métodos print y println sobrecargados para todos

los tipos primitivos.

System.out es de tipo PrintStream

Filtro PrintStream

PrintStream ps;

ps = new PrintStream(new FileOutputStream(“A”));

ps.println(1);

ps.println(3.14);

ps.println(“Hola”);

ps.close(); // Se cierra también el socio

Page 19: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 19 © Francisco J. García Izquierdo

La forma más habitual de usar un OutputStream será combinando varios filtros.

Combinación

DataOutputStream dos;

dos = new DataOutputStream(

new FileOutputStream(“A”)

);

// Se transforma: DataOutput

dos.writeInt(i);

dos.writeDouble(3.14);

dos.writeChars(“Hola”);

// Se vuelca: File

dos.close(); // Se cierran todos

Page 20: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 20 © Francisco J. García Izquierdo

¿Qué se puede comentar sobre la siguiente clase?

class Persona {

private String nombre;

private int edad;

Persona (String nombre, int edad) {

this.nombre = nombre;

this.edad = edad;

}

public void write(FileOutputStream f) throws IOExcepcion {

DataOutputStream dos;

dos = new DataOutputStream(f);

dos.writeUTF(nombre);

dos.writeInt(edad);

}

}

Uso de OutputStreams

class Persona {

private String nombre;

private int edad;

Persona (String nombre, int edad) {

this.nombre = nombre;

this.edad = edad;

}

public void escribe(FileOutputStream f) throws IOExcepcion {

DataOutputStream dos;

dos = new DataOutputStream(f);

dos.writeChars(nombre);

dos.writeInt(edad);

}

}

Page 21: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 21 © Francisco J. García Izquierdo

Uso de OutputStreams

public static void main(String args[]) {

Persona[] v = new Persona[100];

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

v[i] = new Persona(“Pepe” + i, i);

FileOutputStream f =

new FileOutputStream(“Personas.dat”);

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

v[i].escribe(f);

f.close();

}

Page 22: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 22 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 23: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 23 © Francisco J. García Izquierdo

Clase abstracta de la que derivan los demás flujos de entrada.

Fundamentalmente ofrece los siguientes servicios:

public abstract int read() throws IOException

public int read(byte b[]) throws IOException

public int read(byte b[], int off, int len) ) throws IOException

public int available() throws IOException

public void close() throws IOException

InputStream es una clase abstracta. ¿De dónde se recibe el byte que se lee a través de un InputStream?

Dependerá del tipo del stream.

Hay varias clases que derivan de InputStream y redefinen el método read para darle una implementación distinta: FileInputStream.

ByteArrayInputStream.

StringInputStream.

SequenceInputStream.

PipedInputStream.

TelnetInputStream

Clase InputStream

Page 24: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 24 © Francisco J. García Izquierdo

El FileInputStream redefine el método

read para leer el byte de un fichero.

FileInputStream

FileInputStream f;

f = new FileInputStream(“Datos.dat”);

int dato;

while ((dato = f.read()) != -1)

System.out.println(dato);

f.close();

Page 25: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 25 © Francisco J. García Izquierdo

Lectura por bloques

InputStream is = ...;

OutputStream os = ...;

byte buff[] = new byte[buffSize];

int leidos = is.read(buff);

while (leidos != -1) {

os.write(buff);

leidos = is.read(buff);

}

os.close();

InputStream is = ...;

OutputStream os = ...;

byte buff[] = new byte[buffSize];

int leidos = is.read(buff);

while (leidos != -1) {

os.write(buff, 0, leidos);

leidos = is.read(buff);

}

os.close();

Page 26: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 26 © Francisco J. García Izquierdo

El ByteArrayInputStream redefine el método read para leer el byte de un array que se le pase en el constructor.

Ejemplo

byte[] v = new byte[1024];

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

v[i] = i * 2;

ByteArrayInputStream ba;

ba = new ByteArrayInputStream(v);

int dato;

while ((dato = ba.read()) != -1)

System.out.println(dato);

ba.close();

ByteArrayInputStream

byte[] v = new byte[1024];

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

v[i] = i * 2;

ByteArrayInputStream ba;

ba = new ByteArrayInputStream(v);

int dato;

while ((dato = ba.read()) != -1)

System.out.println(dato);

ba.close();

Page 27: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 27 © Francisco J. García Izquierdo

El StringInputStream redefine el método read para leer el siguiente carácter de una cadena que se le pase en el constructor.

Sirve para tratar un String como si fuese un stream

Ejemplo

StringInputStream ba;

ba = new StringInputStream(“Hola”);

int dato;

while ((dato = ba.read()) != -1)

System.out.println(dato);

ba.close();

StringInputStream

StringInputStream ba;

ba = new StringInputStream(“Hola”);

int dato;

while ((dato = ba.read()) != -1)

System.out.println(dato);

ba.close();

Page 28: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 28 © Francisco J. García Izquierdo

Cuando se tienen varios InputStreams que se desean procesar seguidos se pueden concatenar mediante un SequenceInputStream.

De esta manera aparecen como un único InputStream continuo.

FileInputStream f1, f2;

f1 = new FileInputStream(“Datos1.dat”);

f2 = new FileInputStream(“Datos2.dat”);

SequenceInputStream sis;

sis = new SequenceInputStream(f1, f2);

int dato;

while ((dato = sis.read()) != -1)

System.out.println(dato);

sis.close();

SequenceInputStream

FileInputStream f1, f2;

f1 = new FileInputStream(“Datos1.dat”);

f2 = new FileInputStream(“Datos2.dat”);

SequenceInputStream sis;

sis = new SequenceInputStream(f1, f2);

int dato;

while ((dato = sis.read()) != -1)

System.out.println(dato);

sis.close();

Page 29: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 29 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 30: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 30 © Francisco J. García Izquierdo

Un filtro de entrada es un InputStream al cual se le

asocia en su constructor otro InputStream.

Los filtros devuelven la información que a su vez han leído de su InputStream asociado, previa realización

de algún tipo de transformación en la misma.

De esta manera cada filtro añade una funcionalidad adicional al InputStream básico.

Se pueden encadenar varios filtros para obtener varias

funcionalidades combinadas.

FilterInputStream

Page 31: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 31 © Francisco J. García Izquierdo

Los métodos de la clase InputStream solo permiten leer bytes.

Cualquier otro tipo deberán leerse como una secuencia de bytes y recomponerse antes de poder utilizarse.

FileInputStream in = new FileInputStream(“datos.dat”);

int ch1 = in.read();

int ch2 = in.read();

int ch3 = in.read();

int ch4 = in.read();

if ((ch1 | ch2 | ch3 | ch4) < 0)

throw new EOFException();

int i = ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

// Idem para String, float, etc.

Filtro DataInputStream

FileInputStream in = new FileInputStream(“datos.dat”);

int ch1 = in.read();

int ch2 = in.read();

int ch3 = in.read();

int ch4 = in.read();

if ((ch1 | ch2 | ch3 | ch4) < 0)

throw new EOFException();

int i = ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));

// Idem para String, float, etc.

Page 32: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 32 © Francisco J. García Izquierdo

La clase DataInputStream añade la funcionalidad de poder leer todos los tipos primitivos directamente. readBoolean()

readChar

readByte()

readShort()

readInt()

readLong()

readFloat()

readDouble()

readLine()

readFully(byte[] b)

Filtro DataInputStream

Page 33: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 33 © Francisco J. García Izquierdo

DataInputStream dis;

dis = new DataInputStream(new FileInputStream(“A”));

int i = dis.readInt();

double d = dis.readDouble();

String s = dis.readLine();

dis.close(); // Se cierra también el socio

El final del stream se detecta:

readLine() devuelve null

El resto de métodos lanza EOFException

Filtro DataInputStream

DataInputStream dis;

dis = new DataInputStream(new FileInputStream(“A”));

int i = dis.readInt();

double d = dis.readDouble();

String s = dis.readLine();

dis.close(); // Se cierra también el socio

Page 34: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 34 © Francisco J. García Izquierdo

Esquema típico usando un DataInputStream

O con BufferedReader (luego hablaremos de la

diferencia)

Lectura de ficheros de texto

DataInputStream dis = new DataInputStream(...);

String linea;

while ( (linea = dis.readLine()) != null) {

// Hacer algo con linea

}

BufferedReader br = new BufferedReader (...);

String linea;

while ( (linea = br.readLine()) != null) {

// Hacer algo con linea

}

Page 35: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 35 © Francisco J. García Izquierdo

La forma más habitual de usar un InputStream será combinando varios filtros.

Combinación

DataInputStream dis;

dis = new DataInputStream(

new FileInputStream(“A”)

);

int i = dis.readInt();

double d = dis.readDouble();

String s = dis.readLine();

dis.close(); // Se cierra también el socio

Page 36: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 36 © Francisco J. García Izquierdo

¿Qué se puede comentar sobre la siguiente clase?

Uso de InputStreams

public class Persona {

private String nombre;

private int edad;

public Persona (String nombre, int edad) {

this.nombre = nombre;

this.edad = edad;

}

public void lee(FileInputStream f) throws IOException {

DataInputStream dis;

dis = new DataInputStream(f);

nombre = dis.readUTF();

edad = dis.readInt();

}

}

Page 37: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 37 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 38: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 38 © Francisco J. García Izquierdo

Los streams están orientados a la E/S de bytes

Los Readers y los Writers están orientados a la E/S de caracteres.

Tenemos la mala costumbre de asumir que todo el texto es ASCII (en este caso hay equivalencia entre byte y char)

Pero no en todas las partes del mundo pasa eso.

Su existencia se justifica por la necesidad de escribir caracteres en distintos juegos de caracteres y así facilitar la internacionalización

Existe una jerarquía paralela entre Readers e InputStreams (y Writers y OutputStreams). Ej: FileInputStream – FileReader.

Para convertir un InputStream en un Reader existe InputStreamReader (y para writers OutputStreamWriter)

La recomendación es que siempre que se vaya a escribir texto se escriba con Writer.

Readers y Writers

Page 39: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 39 © Francisco J. García Izquierdo

Internamente los caracteres en Java se codifican en Unicode (siempre 2 bytes por carácter) ‘a’ es el carácter 97 (0x0061 ó \u0061), ‘á’ el 225 (0x00E1); € el 8364 (0x20AC).

Cuando los caracteres se escriben en un writer se usa un determinado encoding para ello Encoding: correspondencia entre caracteres Unicode y bytes usados para representar ese

carácter xej. en un fichero.

El encoding depende de la región del mundo Nosotros usamos Latin1 (ISO-8859-1) o Windows 1252 (o Cp-1252)

Un byte por carácter (solo se puede escribir 256, menos que los caracteres Unicode)

Si un carácter no existe se escribe ?

Ejemplo: ‘a’ es el byte 0x61, el ‘á’ es el 0xE1; el € es el 0x80 (en Cp-1252)

Universalmente se puede usar UTF-8 Número variable de bytes por carácter

Ej.: ‘a’ es el byte 0x61, ‘á’ un par de bytes 0xC3 0xA1; € tres bytes 0xE2 0x82 0xAC

Al leer los bytes, para transformarlos en caracteres, hay que usar el mismo encoding. Si no se puede leer “basura” Si escribo en UTF-8 el á, y leo en ISO-8859-1, leeré Ã ¡

Si no se indica nada se escoge el encoding por defecto (en Windows el ISO-8859-1, o Cp-1252; en Linux el UTF-8) Cuando se escribe/lee un String en/a un Output/InputStream se está usando el encoding

por defecto

Sobre codificación de caracteres

Page 40: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 40 © Francisco J. García Izquierdo

Esquema típico usando un DataInputStream

O con BufferedReader

Lectura de ficheros de texto

DataInputStream dis = new DataInputStream(...);

String linea;

while ( (linea = dis.readLine()) != null) {

// Hacer algo con linea

}

BufferedReader br = new BufferedReader (...);

String linea;

while ( (linea = br.readLine()) != null) {

// Hacer algo con linea

}

En Windows no dará

problemas, pero sí en

Linux

Page 41: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 41 © Francisco J. García Izquierdo

Introducción

Salida (Out…)

Filtros de salida

Entrada (Input…)

Filtros de entrada

Readers y Writers

Clase File

Agenda

Page 42: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 42 © Francisco J. García Izquierdo

Los objetos de la clase File representan ficheros en un sistema de ficheros

Sólo los representan

No se escribe ni lee en los fichero a través de un File

Puede que el fichero final ni siquiera exista (exists() )

Sirven también para directorios

Permite obtener el contenido del directorio (list())

Permiten crear directorios (mkDir(), mkDirs())

Permiten acceder a propiedades sobre el fichero: tamaño (length()), solo lectura (canWrite()), fecha de modificación (lastModified()), nombre completo (getAbsolutePath()), …

Permiten realizar operaciones de destrucción y movimiento de ficheros: renameTo(File dest), delete(), deleteOnExit()

Clase File

Page 43: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Departamento de Matemáticas y Computación Grado en Informática Programación de Bases de Datos

Serialización de objetos

Page 44: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 44 © Francisco J. García Izquierdo

La serialización es el proceso de transformar

un objeto en una secuencia de bytes y su

reconstrucción posterior a partir de la misma

La secuencia de bytes obtenida mediante la

serialización podrá ser almacenada en un

fichero, transmitida por la red, etc...

Posteriormente se podrá recuperar una copia

del objeto en el mismo estado en el que

estaba cuando se serializó

Introducción

Page 45: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 45 © Francisco J. García Izquierdo

Para poder leer y escribir objetos simplemente hay que

utilizar dos nuevos tipos de streams: el ObjectOutputStream y el ObjectInputStream.

La única condición que debe cumplir una clase para ser serializable es implementar el interface Serializable

Es un “marker”, no tiene ningún método y simplemente sirve

para marcar la clase como serializable

Si no serializable java.io.NotSerializableException

Consecuencia: si una clase es serializable lo serán todas sus

derivadas.

Introducción

Page 46: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 46 © Francisco J. García Izquierdo

Introducción - Ejemplo

class A implements Serializable{

public int i;

}

. . .

// Escritura de una instancia de una clase serializable

A a = new A();

FileOutputStream f = new FileOutputStream(“prueba.ser”);

ObjectOutputStream oos = new ObjectOutputStream(f);

oos.writeObject(a);

oos.close();

. . .

// Lectura de una instancia de una clase serializable

FileInputStream f = new FileInputStream(“prueba.ser”);

ObjectInputStream ois = new ObjectInputStream(f);

A a = (A) ois.readObject();

ois.close(); Ver formato

Page 47: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 47 © Francisco J. García Izquierdo

En la serialización se almacena el contenido de todos los atributos de la instancia, incluidos los privados y los heredados. Por tanto deberán ser de tipos primitivos o de tipos Serializables. Si tiene algún atributo no serializable, la clase no puede serializarse (a

no ser que se marque como transient)

No se almacenan Campos transient

Campos static

Con la instancia se serializan todos los objetos alcanzables desde él. Es decir, se serializa todo grafo de objetos alcanzable desde el objeto inicial. Si en el grafo hay varias referencias a una misma instancia esta sólo

se almacena una vez.

Se almacena el estado del objeto, no el código, que está en el fichero .class. Para de-serializar un objeto es necesario disponer de su fichero de clase.

Introducción

Page 48: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 48 © Francisco J. García Izquierdo

Serializar un array implica serializar todos

sus elementos.

Los atributos estáticos no se serializan

En el proceso de reconstrucción del objeto

no se llama al constructor de las clases

serializables

Sus atributos se inicializan a partir de la

información del stream.

Introducción

Page 49: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 49 © Francisco J. García Izquierdo

Hay veces que no interesa guardar todos los atributos de una instancia:

Información confidencial: ej. un string que guarde una password.

Información redundante: atributos derivados de otros que se tienen ya calculados por eficiencia, pero que no es necesario guardarlos.

Atributos que no se pueden serializar, ya que son de un tipo no serializable.

Los atributos marcados con el modificador transient no se serializan. A la hora de la lectura se inicializan al valor por defecto del tipo (enteros a cero, referencias a null, etc...)

Atributos transient

class A implements Serializable{

public transient int i;

}

Page 50: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 50 © Francisco J. García Izquierdo

Hay ocasiones en que interesa controlar el proceso de escritura: Se desean guardar ciertos atributos en otro formato más compacto que

el que mantienen en memoria

Si se desea escribir información adicional junto con los atributos de la instancia

Si la clase define el método writeObject este será llamado en el momento de la escritura. private void writeObject(ObjectOutputStream oo) throws

IOException

Escritura de instancias

class A implements Serializable{

public transient int i;

private void writeObject(ObjectOutputStream oos) throws IOException {

// Escribir lo que se quiera

}

}

Page 51: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Grado en Informática – Programación de Bases de datos 52 © Francisco J. García Izquierdo

Así mismo hay ocasiones en que interesa controlar el proceso de lectura:

Inicializar atributos que se guardaron en otro formato (por ejemplo volver a obtener la imagen a partir del nombre del fichero).

Leer la información adicional que se escribió en writeObject.

Dar un valor adecuado a los atributos transient.

Si la clase define el método readObject este será llamado en el momento de la lectura private void readObject(ObjectIntputStream stream)

throws IOException, ClassNotFoundException

Lectura de instancias

class A implements Serializable{

public transient int i;

private void readObject(ObjectIntputStream stream)

throws IOException, ClassNotFoundException {

// Escribir lo que se quiera

}

}

Page 52: Java IO - Streams - unirioja.es · La E/S de Java se realiza a través de flujos (streams). ... el byte a un array dinámico (en memoria). Añade los métodos: public byte[] toByteArray()

Departamento de Matemáticas y Computación Grado en Informática Programación de Bases de Datos

os.close()