Você está na página 1de 72

Programao por Objectos Java

Parte 11: Entradas / Sadas

LEEC@IST

Java 1/72

Introduo
comum separar os dados que entram ou saem do ambiente para o programa em informao binria e informao textual. Informao binria: constituda por zeros e uns que codificam qualquer tipo de dados e que tm que ser intepretados pela aplicao. Informao textual: constituda por letras, dgitos, caracteres especiais que no Java corresponde ao tipo primitivo char (UTF-16).

LEEC@IST

Java 2/72

Pacote java.io
Todas as classes de manipulao de ficheiros esto contidas no pacote java.io. Classes que acedem a ficheiros devem ter a directiva:
import java.io.*;

LEEC@IST

Java 3/72

Pacote java.io
O pacote java.io dividido em 5 partes:
1. Fluxo binrio (byte stream):
fluxo de entrada (input stream). fluxo de sada (output stream). leitores (readers). escritores (writers).

2. Fluxo de caracteres (character stream):

3. Fluxo de dados, que manipulam tipos primitivos de dados (int,) e cadeias de caracteres (String). 4. Fluxo de objectos, que transcrevem objectos para Bytes e vice-versa. 5. Classe File, de manipulao dos atributos de ficheiros.

LEEC@IST

Java 4/72

Fluxos pr-definidos
No J2SE existe a classe esttica final System, derivada de Object. A classe System possui trs atributos estticos:
InputStream in: fluxo de entrada do programa (normalmente teclado) PrintStream out: fluxo de sada do programa (normalmente monitor) PrintStream err: fluxo de envio das mensagens de erro (normalmente coincide com System.out)

LEEC@IST

Java 5/72

Fluxos binrios
InputStream: classe abstracta que l fluxos binrios de informao. OutputStream: classe abstracta que escreve fluxos binrios de informao. PrintStream: subclasse concreta de OutputStream que escreve fluxos no necessariamente binrios de informao.

LEEC@IST

Java 6/72

Classe InputStream (1)


Alguns mtodos da classe InputStream:
void close() Encerra o fluxo binrio de entrada e liberta todos os recursos associados. abstract int read() L o byte seguinte do fluxo binrio de entrada. O byte lido retornado como um int. Se nenhum byte lido retorna -1. int read(byte[] b) L um determinado nmero de bytes do fluxo binrio de entrada para o tampo b. O nmero de bytes lidos retornado. int read(byte[] b, int off, int len) L no mximo len bytes do fluxo binrio de entrada para o tampo b, colocando-os em b apartir da posio off. O nmero de bytes lidos retornado.

LEEC@IST

Java 7/72

Classe InputStream (2)


long skip(long n) Salta n bytes do fluxo binrio de entrada. Pode acontecer que se salte um nmero m<n de bytes, possivelmente m=0, por diversas razes, EOF antes dos n bytes uma das razes. retornado o nmero de bytes saltado. Se n negativo, no foram saltados bytes. boolean markSupported() Verifica se o fluxo binrio de entrada suporta marcas. void mark(int readLimit) Marca a posio actual no fluxo binrio de entrada. O argumento readLimit o nmero mximo de bytes que podem ser lidos antes da marca se tornar invlida. void reset() Regressa marca mais recente.

LEEC@IST

Java 8/72

Classe OutputStream
Alguns mtodos da classe OutputStream:
close() Encerra o fluxo binrio de sada e liberta todos os recursos associados. void flush() Fora envio de informao contida num tampo para o destino. void write(byte[] b) Escreve b.length bytes da tabela de bytes b para o fluxo binrio de sada. void write(byte[] b, int off, int len) Escreve len bytes da tabela de bytes b, comeando na posio off para o fluxo binrio de sada.

LEEC@IST

Java 9/72

Classe PrintStream
Alguns mtodos da classe PrintStream:
void print(boolean b) void print(char c) void print(char[] c) void print(double d) void print(float f) void print(int i) void print(long l) void print(Object obj) void print(String s) Imprime o correspondente tipo. void println() Termina a linha corrente.

LEEC@IST

Java 10/72

Fluxos binrios para ficheiros


File: subclasse concreta de Object que abstrai a representao de um ficheiro e caminho de directorias. FileDescriptor: subclasse final de Object que representa um ficheiro aberto. FileInputStream: subclasse concreta de InputStream que l fluxos binrios de informao de um ficheiro (File ou FileDescriptor). FileOutputStream: subclasse concreta de OutputStream que escreve fluxos binrios de informao para um ficheiro (File ou FileDescriptor).
LEEC@IST Java 11/72

Class File
Alguns construtores da classe File:
File(String pathname) Cria um ficheiro com a pathname recebida. A pathname pode ser relativa ou absoluta. No caso de ser relativa, resolvida tendo em considerao a directoria corrente do utilizador.

Alguns mtodos da classe File:


boolean exists() boolean canRead() boolean canWrite() boolean delete() long length() String getName() String getPath()
LEEC@IST

Testa existncia fsica do ficheiro. Testa privilgios de leitura do ficheiro. Testa privilgios de escrita do ficheiro. Apaga o ficheiro. Retorna a dimenso do ficheiro. Retorna o nome do ficheiro. Retorna o caminho do ficheiro.
Java 12/72

Classe FileDescriptor
Um objecto FileDescriptor representa um valor dependente do sistema operativo que descreve um ficheiro aberto. As aplicaes no devem criar objectos do tipo FileDescriptor, estes devem antes ser obtidos apartir do mtodo getFD dos FileInputStream e FileOutputStream.

LEEC@IST

Java 13/72

Classe FileInputStream
Construtores da classe FileInputStream:
FileInputStream(File file) FileInputStream(FileDescriptor fdObj) FileInputStream(String name) Cria um FileInputStream a partir do ficheiro recebido.

Para alm dos mtodos tpicos de close, read, skip, etc, tem ainda o seguinte mtodo:
FileDescriptor getFD() Retorna o objecto FileDescriptor que representa o ficheiro, no sistema de ficheiros, que est a ser usado pelo FileInputStream.

LEEC@IST

Java 14/72

Classe FileOutputStream
Construtores da classe FileOutputStream:
FileOutputStream(File file) FileOutputStream(File file, boolean append) FileOutputStream(FileDescriptor fdObj) FileOutputStream(String name) FileOutputStream(String name, boolean append) Cria um FileOutputStream a partir do ficheiro recebido. Os construtores que recebem um boolean append escrevem no fim do ficheiro se append for true e escrevem no incio do ficheiro se append for false.

Para alm dos mtodos tpicos de close, write, etc, tem ainda o seguinte mtodo:
FileDescriptor getFD() Retorna o objecto FileDescriptor que representa o ficheiro, no sistema de ficheiros, que est a ser usado pelo FileOutputStream.
LEEC@IST Java 15/72

Exemplos de fluxos binrios


import java.io.*; // ... int nbytes=0; FileInputStream f = new FileInputStream(teste); while(f.read() != -1) nBytes++; System.out.println(Nmero = + nBytes); f.close() // ... import java.io.*; // ... FileOutputStream f = new FileOutputStream(teste); f.write(65); f.write(66); f.write(67); f.close() // ...

LEEC@IST

Java 16/72

Fluxos de caracteres
Reader: a classe abstracta que l fluxos de caracteres. Writer: a classe abstracta que escreve fluxos de caracteres. InputStreamReader: a subclasse concreta de Reader que l fluxos binrios de informao e que os descodifica em caracteres usando um determinado charset. OutputStreamWriter: a subclasse concreta de Writer que codifica caracteres em bytes, usando um determinado charset, e os escreve em fluxos binrios de informao.

LEEC@IST

Java 17/72

Charsets padro
Qualquer implementao da plataforma Java suporta os seguintes charsets:
US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set. ISO-8859-1 ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1. UTF-8 Eight-bit UCS Transformation Format. UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order. UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order. UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark.
Java 18/72

LEEC@IST

Classe InputStreamReader (1)


Alguns construtores da classe InputStreamReader:
InputStreamReader(InputStream in) Cria um InputStreamReader com um charset default da correspondente JVM (normalmente o charset do sistema operativo). InputStreamReader(InputStream in, String charsetName) Cria um InputStreamReader com o charset recebido como parmetro.

A classe InputStreamReader um embrulho dum objecto InputStream.

LEEC@IST

Java 19/72

Classe InputStreamReader (2)


Alguns mtodos da classe InputStreamReader:
void close() Encerra o fluxo de entrada e liberta todos os recursos associados. String getEncoding() Retorna o nome do charset usado pelo fluxo de entrada. int read() L um caracter do fluxo de entrada. O caracter lido retornado como um int. Se nenhum caracter lido retorna -1. int read(char[] cbuf, int off, int len) L no mximo len caracter do fluxo de entrada para o tampo cbuf, colocandoos em cbuf apartir da posio off. O nmero de caracteres lidos retornado. Se nenhum caracter lido retorna -1.

LEEC@IST

Java 20/72

Classe OutputStreamWriter (1)


Alguns construtores da classe OutputStreamWriter:
OutputStreamWriter(OutputStream in) Cria um OutputStreamWriter com um charset default da correspondente JVM (normalmente o charset do sistema operativo) OutputStreamWriter(OutputStream in, String charsetName) Cria um OutputStreamWriter com o charset recebido como parmetro.

A classe OutputStreamWriter um embrulho dum objecto OutputStream.

LEEC@IST

Java 21/72

Classe OutputStreamWriter (2)


Alguns mtodos da classe OutputStreamWriter:
void close() Encerra o fluxo de entrada e liberta todos os recursos associados. void flush() Fora envio de informao contida num tampo para o destino. String getEncoding() Retorna o nome do charset usado pelo fluxo de entrada. void write(char[] cbuf, int off, int len) Escreve len caracteres da tabela cbuf, comeando na posio off para o fluxo de sada. void write(String str, int off, int len) Escreve len caracteres da String str, comeando na posio off para o fluxo de sada.

LEEC@IST

Java 22/72

Fluxos de carateres para ficheiros


FileReader: a subclasse concreta de InputStreamReader para ler ficheiros de

caracteres.
FileWriter: a subclasse concreta de OutputStreamWriter para escrever para

ficheiros de caracteres.

LEEC@IST

Java 23/72

Classe FileReader
Construtores da classe FileReader:
FileReader(File file) FileReader(FileDescriptor fdObj) FileReader(String name) Cria um FileReader a partir do ficheiro recebido.

LEEC@IST

Java 24/72

Classe FileWriter
Construtores da classe FileWriter:
FileWriter(File file) FileWriter(File file, boolean append) FileWriter(FileDescriptor fdObj) FileWriter(String name) FileWriter(String name, boolean append) Cria um FileWriter a partir do ficheiro recebido. Os construtores que recebem um boolean append escrevem no fim do ficheiro se append for true e escrevem no incio do ficheiro se append for false.

LEEC@IST

Java 25/72

Exemplos de fluxos de caracteres (1)


import java.io.*; // ... int c, uns=0; FileReader f = new FileReader(teste); while(c = f.read() != -1) if ((char)c == 1) uns++; System.out.println(Ocorreram = + uns + uns!); f.close() // ...

LEEC@IST

Java 26/72

Exemplos de fluxos de caracteres (2)


class LeituraDeInteiro { public static void main(String[] args) throws IOException { int ch, value=0; Reader in = args.length==0 ? new InputStreamReader(System.in) : new FileReader(args[0]); for( ;(ch=in.read()!=-1; ) value=10*value+ch-(int)'0'; System.out.println("Inteiro lido = " + value); } }

LEEC@IST

Java 27/72

Transferncia por tampo (1)


Tipicamente, os fluxos de entrada e sada transferem de imediato cada dado. Para tornar as operaes de leitura/escrita mais eficientes, deve usar-se um tampo (buffer).

LEEC@IST

Java 28/72

Transferncia por tampo (2)


<<abstract>> InputStream <<abstract>> OutputStream

FilterInputStream FilterOutputStream

Transferncia por tampo


DataInputStream BufferedInputStream

DataOutputStream BufferedOutputStream PrintStream

Transferncia imediata
LEEC@IST Java 29/72

Transferncia por tampo (3)


FilterInputStream: a subclasse concreta de InputStream que embrulha outro fluxo de entrada que usa para transferncia de dados. FilterOutputStream: a subclasse concreta de OutputStream que embrulha outro fluxo de sada que usa para transferncia de dados. FilterReader: a subclasse abstracta de Reader que embrulha outro fluxo de entrada que usa para transferncia de dados. FilterWriter: a subclasse abstracta de Writer que embrulha outro fluxo de sada que usa para transferncia de dados.
LEEC@IST Java 30/72

Transferncia por tampo (4)


Tipicamente, subclasses de FilterInputStream, FilterOutputStream, FilterReader e FilterWriter, redefinem algum dos seus mtodos e/ou adicionam membros com novas funcionalidades.

LEEC@IST

Java 31/72

Transferncia por tampo (5)


public class ConversorParaMaiusculas extends FilterReader { public ConversorParaMaiusculas(Reader in) { super(in); } public in read() throws IOException { int c = super.read(); return (c==-1 ? c : Character.toUpperCase((char)c); } public int read(char[] buf, int offset, int count) throws IOException { int n = super.read(buf,offset,count); int ultimo = offset+n; for (int i=offset;i<ultimo;i++) buf[i] = Character.toUpperCase(buf[i]); return n; } }
LEEC@IST Java 32/72

Transferncia por tampo (6)


public static void main(String[] args) throws IOException { FileReader src = new FileReader(args[0]); FilterReader fr = new ConversorParaMaiusculas(src); int c; while ((c=f.read())!=-1) System.out.print((char)c); System.out.println(); }

LEEC@IST

Java 33/72

Transferncia por tampo (7)


Fluxos com transferncia por tampo:
BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter

LEEC@IST

Java 34/72

Transferncia por tampo (8)


BufferedInputStream: a subclasse concreta de FilterInputStream com transferncia por tampo e mtodos mark e reset. BufferedOutputStream: a subclasse concreta de FilterOutputStream com transferncia por tampo. BufferedReader: a subclasse concreta de Reader com transferncia por tampo e mtodos mark e reset. BufferedWriter: a subclasse concreta de Writer com transferncia por tampo.
LEEC@IST Java 35/72

Transferncia por tampo (9)


Construtores da classe BufferedInputStream:
BufferedInputStream(InputStream in) BufferedInputStream(InputStream in, int size) Cria um BufferedInputStream que embrulha o fluxo de entrada recebido. O size recebido no segundo construtor relativo ao tamanho do tampo.

LEEC@IST

Java 36/72

Transferncia por tampo (10)


Quando um read inicialmente chamado num BufferedInputStream, este chama um read no correspondente fluxo de entrada, enchendo o tampo (se existirem dados suficientes). Novas chamadas a read retornam dados do tampo. Quando todo o tampo foi lido, chamado de novo o read sobre o correspondente fluxo de entrada. Este processo continua at que o correspondente fluxo de entrada completamente lido.
File BufferedInputStream FileInputStream
LEEC@IST

tampo

Programa Java { }
Java 37/72

Transferncia por tampo (11)


Construtores da classe BufferedOutputStream:
BufferedOutputStream(OutputStream out) BufferedOutputStream(OutputStream out, int size) Cria um BufferedOutputStream que embrulha o fluxo de sada recebido. O size recebido no segundo construtor relativo ao tamanho do tampo.

LEEC@IST

Java 38/72

Transferncia por tampo (12)


De forma semelhante ao read:
S quando um write, chamado num BufferedOutputStream, enche o tampo, que chamado um write no correspondente fluxo de sada para esvaziar o tampo. Este tampo pode fazer com que vrios pequenos pedidos de write num BufferedInputStream sejam transformados apenas num write no correspondente fluxo de sada.

LEEC@IST

Java 39/72

Transferncia por tampo (13)


A escrita feita via tabelas de bytes:
void write(byte[] b,int off,int len) void write(byte b)

Antes de fechar um ficheiro de escrita com tampo, necessrio chamar o mtodo flush, para todos os bytes armazenados serem enviados para o meio:
void flush()

O fecho de ficheiros executado na chamada do mtodo definido na classe FilterOutputStream:


void close()
LEEC@IST Java 40/72

Transferncia por tampo (14)


Construtores da classe BufferedReader:
BufferedReader(Reader in) BufferedInputStream(Reader in, int size) Cria um BufferedReader que embrulha o fluxo de entrada recebido. O size recebido no segundo construtor relativo ao tamanho do tampo.

Construtores da classe BufferedWriter:


BufferedWriter(Writer out) BufferedWriter(Writer out, int size) Cria um BufferedWriter que embrulha o fluxo de sada recebido. O size recebido no segundo construtor relativo ao tamanho do tampo.
LEEC@IST Java 41/72

Transferncia por tampo (15)


Alguns mtodos da classe BufferedWriter:
void newLine() Escreve um separador de linha. Depende do sistema (no necessariamente o \n).

LEEC@IST

Java 42/72

Exemplos de criao de fluxos com transferncia por tampo


new BufferedInputStream(new FileInputStream(foo.in)); new BufferedReader(new FileReader(foo.in)); new BufferedOutputStream(new FileOutputStream(foo.out)); new BufferedWriter(new FileWriter(foo.out));

LEEC@IST

Java 43/72

Fluxos de dados (1)


DataInput: interface que define mtodos de leitura para os tipos primivitos e cadeias de caracteres. DataOutput: interface que define mtodos de escrita para os tipos primitivos e cadeias de caracteres. DataInputStream: implementao da interface DataInput. DataOutputStream: implementao da interface DataOutput. RandomAccessFile: classe concreta que implementa as interfaces DataInput e DataOutput para acesso aleatrio a um ficheiro.
LEEC@IST Java 44/72

Fluxos de dados (2)


Mtodos de leitura/escrita: Tipo
boolean char byte short int long float double String
LEEC@IST

Escrita
void writeBoolean(boolean) void writeChar(char) void writeByte(byte) void writeShort(short) void writeInt(int) void writeLong(long) void writeFloat(float) void writeDouble(double) void writeUTF(String)

Leitura
boolean readBoolean() char readChar() byte readByte() short readShort() int readInt() long readLong() float readFloat() double readDouble() String readUTF()
Java 45/72

Fluxos de dados (3)


Os ficheiros binrios: So fluxos de bytes. Tm de ser abertos explicitamente pelo programador antes de serem acedidos. Abertura de ficheiros:
Erro na abertura gera excepo FileNotFoundException.
DataOutputStream idOut = new DataOutputStream(new FileOutputStream(foo.out)); DataInputStream idIn = new DataInputStream(new FileInputStream(foo.in));

LEEC@IST

Java 46/72

Exemplos de fluxos de dados (1)


import java.io.*; public class Teste { public static void main(String[] args){ DataOutputStream idOut; try { idOut = new DataOutputStream( new FileOutputStream(args[0])); for(int k=0;k<10;k++) idOut.writeUTF("Linha " + k + "\n"); idOut.close(); } catch(IOException e) { System.out.println(e.getMessage()); } } }

LEEC@IST

Java 47/72

Exemplos de fluxos de dados (2)


import java.io.*; public class Teste { public static void main(String[] args){ DataOutputStream idOut; try { idOut = new DataOutputStream( new BufferedOutputStream( new FileOutputStream(args[0]))); for(char c='a';c<='z';c++) { idOut.write((byte)c); idOut.write((byte)'\n'); } idOut.flush(); idOut.close(); } catch(IOException e) { System.out.println(e.getMessage()); } } }

LEEC@IST

Java 48/72

Exemplos de fluxos de dados (3)


BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); try { String input = stdin.readLine(); System.out.println("Linha comando: " + input); } catch(IOException e) { System.err.println(Erro na leitura do comando); }

LEEC@IST

Java 49/72

Acesso sequencial e aleatrio


Existem duas formas padro de acesso a um dado ficheiro, acesso sequencial e aleatrio. Acesso sequencial limitado por uma ordem sequencial de acesso informao seguinte sempre colocada frente da informao anterior. Acesso aleatrio permite avanar e recuar de forma arbitrria.

LEEC@IST

Java 50/72

Classe RandomAccessFile (1)


O acesso aletario a ficheiros implementado pela classe RandomAccessFile, classe concreta que deriva de Object e que implementa as interfaces DataInput e DataOutput. Construtores da classe RandonAccessFile:
RandomAccessFile(File file, String mode) RandomAccessFile(String name, String mode) Cria um ficheiro para ler/escrever com acesso aleatrio de/para o ficheiro recebido. O modo representa o modo de acesso do ficheiro aberto, podendo ser: r (apenas leitura) ou rw (leitura e escrita), entre outros.

LEEC@IST

Java 51/72

Classe RandomAccessFile (2)


Alguns mtodos de leitura:
int read() int read(byte[]) int read(byte[], int offset, int length) boolean readBoolean() byte readByte() char readChar() double readDouble() float readFloat() int readInt() long readLong() short readShort() String readUTF()

LEEC@IST

Java 52/72

Classe RandomAccessFile (3)


Alguns mtodos de escrita:
void void void void void void void void void void void void void
LEEC@IST

write(byte[]) write(byte[], int offset, int length) writeBoolean(boolean b) writeByte(int v) writeBytes(String s) writeChar(int v) writeChars(String s) writeDouble(double v) writeFloat(float v) writeInt(int v) writeLong(long v) writeShort(int v) writeUTF(String str)
Java 53/72

Classe RandomAccessFile (4)


Alguns mtodos de posicionamento:
void seek(long pos) Posiciona-se no local indicado pelo parmetro (se valor for superior ao tamanho no ficheiro, posiciona-se no fim). long length() Retorna comprimento do ficheiro. long setLength(long newLength) Altera comprimento do ficheiro. int skipBytes(int n) Salta por cima de um nmero de bytes do ficheiro de entrada (valor efectivo indicado pelo retorno).

LEEC@IST

Java 54/72

Classe RandomAccessFile (5)


File dados = new File(..,info); RandomAcessFile f = new RandomAcessFile(dados, rw); for(int i=65;i<91;i++) f.write(i) // escreve o alfabeto byte[] ler = new byte[10]; f.seek(4); // salta para o quinto byte f.read(ler,0,5); // l as prximas 5 posies for(int=0;i<5;i++) System.out.println((char)ler[i] + :); f.seek(3); // salta para o quarto byte System.out.println((char)f.read());

No terminal imprimido

E:F:G:H:I:D

LEEC@IST

Java 55/72

InputStream Hierarchy
<<abstract>> InputStream

ObjectInputStream

FilterInputStream

FileInputStream

DataInputStream

BufferedInputStream

LEEC@IST

Java 56/72

Reader Hierarchy

LEEC@IST

Java 57/72

RandomAcessFile Hierarchy

LEEC@IST

Java 58/72

Fluxos de objectos
ObjectInputStream: a subclasse concreta de InputStream para leitura de objectos serializados. ObjectOutputStream: a subclasse concreta de OutputStream para serializao de objectos. Serializable: a interface que tem de ser implementada pelas classes que pretendem oferecer serializao.
As classes ObjectInputStream e ObjectOutputStream, quando usados conjuntamente com as classes FileInputStream e FileOutputStream, respectivamente, permitem guardar de forma persistente os objectos duma aplicao.
Java 59/72

LEEC@IST

Classe ObjectInputStream (1)


Alguns construtores da classe ObjectInputStream:
ObjectInputStream(InputStream in) Cria um ObjectInputStream que embrulha o fluxo de entrada recebido.

Alguns mtodos da classe ObjectInputStream:


boolean defaultReadObject() L do fluxo de entrada os valores dos atributos no estticos e no transientes do objecto (atributos da classe e todas as superclasses). Object readObject() L do fluxo de entrada o objecto.

Classes que pretendam serializao atpica devem implementar o mtodo:


private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException;
LEEC@IST Java 60/72

Classe ObjectInputStream (2)


Outros mtodos de leitura:
int read() int read(byte[], int offset, int length) boolean readBoolean() byte readByte() char readChar() double readDouble() float readFloat() int readInt() long readLong() short readShort() String readUTF()

LEEC@IST

Java 61/72

Classe ObjectOutputStream (1)


Alguns construtores da classe ObjectOutputStream:
ObjectOutputStream(OutputStream out) Cria um ObjectOutputStream que embrulha o fluxo de sada recebido.

Alguns mtodos da classe ObjectInputStream:


protected boolean defaultWriteObject() Escreve no fluxo de sada os atributos no estticos e no transientes do objecto (atributos da classe e todas as superclasses). void writeObject(Object obj) Escreve no fluxo de sada o objecto obj.

Classes que pretendam serializao atpica devem implementar o mtodo:


private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException;
LEEC@IST Java 62/72

Classe ObjectInputStream (2)


Outros mtodos de escrita:
void void void void void void void void void void void void void
LEEC@IST

write(byte[]) write(byte[], int offset, int length) writeBoolean(boolean b) writeByte(int v) writeBytes(String s) writeChar(int v) writeChars(String s) writeDouble(double v) writeFloat(float v) writeInt(int v) writeLong(long v) writeShort(int v) writeUTF(String str)
Java 63/72

Exemplos de fluxos de objectos (1)


FileOutputStream fos = new FileOutputStream(foo.out); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeInt(12345); oos.writeObject(Hoje); oos.writeObject(new Date()); oos.close(); fos.close(); FileInputStream fis = new FileInputStream(foo.out); ObjectInputStream ois = new ObjectInputStream(fis); int i = ois.readInt(); String hoje = (String) ois.readObject(); Date data = (Data) ois.readObject(); ois.close(); fis.close();

LEEC@IST

Java 64/72

Exemplos de fluxos de objectos (2)


Serializao de um objecto HashMap num ficheiro para uso futuro:
FileOutputStream fos = new FileOutputStream(hm.out); ObjectOutputStream oos = new ObjectOutputStream(fos); HashMap<?,?> hm = getHashMap(); oos.writeObject(hm);

Uma nova cpia do objecto pode ser reconstruda a partir da serializao anterior:
FileInputStream fis = new FileInputStream(hm.out); ObjectInputStream ois = new ObjectInputStream(fis); HashMap<?,?> hm = (HashMap<?,?>) ois.readObject();

LEEC@IST

Java 65/72

Partilha de referncias na serializao de objectos (1)


A serializao preserva a integridade do grafo dos objectos em memria:
chave: rosa entrada: hm chave: rose entrada: rose.jpg

Quando o HashMap reconstrudo a partir da serializao, existiro apenas referncias para um objecto rose.jpp, e no referncias para duas cpias separadas de rose.jpg.
LEEC@IST Java 66/72

Partilha de referncias na serializao de objectos (2)


Quando tal no pretendido podem usar-se os seguintes mtodos:
void writeUnshared(Object obj) Escreve o objecto obj para o fluxo de sada, sem partilha de referncias. Isto , escreve o objecto como um objecto distinto, em vez de usar uma referncia para a correspondente serializao desse objecto. Qualquer objecto serializado com este mtodo ter uma nica referncia para ele quando for reconstrudo em memria. Object readUnshared() L um objecto sem partilha de referncia do fluxo de entrada. O objecto suposto ser nico, se o objecto uma referncia para um objecto j reconstrudo uma excepo ObjectStreamException lanada. Da mesma forma, se mais tarde se tentar reconstruir um objecto para a mesma referncia uma excepo ObjectStreamException lanada.
LEEC@IST Java 67/72

Interface Serializable (1)


Os objectos de uma aplicao podem ser escritos num fluxo apenas se a sua classe concretizar a interface Serializable. Todos os atributos de um objecto que se pretendem serializar devem ser instncia de uma classe que concretiza Serializable. Se se pretender que o valor de um atributo no seja serializado, usar na sua definio o qualificador transient (na realidade, enviado o literal null). A interface Serializable no tem atributos nem mtodos.
LEEC@IST Java 68/72

Interface Serializable (2)


public class Nome implements java.io.Serializable { private String nome; private long id; private transient boolean hashSet = false; private transient int hash; private static long proxID = 0; public Nome(String nome) { this.nome = nome; id = proxId++; } public int hashCode() { if (!hashSet) { hash = nome.hashCode(); hashSet = true; } return hash; } //redefinio de equals e outros mtodos }
LEEC@IST Java 69/72

Interface Serializable (3)


public class Nome implements java.io.Serializable { private String nome; private long id; private transient int hash; private static long proxID = 0; public Nome(String nome) { this.nome = nome; id = nextId++; hash = nome.hashCode(); } private void writeObject(ObjectOutputStream out) throws IOException { out.writeUTF(nome); out.writeLong(id); } // ... continua no prximo slide

LEEC@IST

Java 70/72

Interface Serializable (4)


private void readObject(ObjectInputStream in) throws IOException, ClassNotFoubdException { nome = in.readUTF(); id = in.readLong(); hash = name.hashCode(); } public int hashCode() { return hash; } //redefinio de equals e outros mtodos }

LEEC@IST

Java 71/72

Interface Serializable (5)


private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoubdException { in.defaultReadObject(); hash = nome.hashCode(); }

LEEC@IST

Java 72/72

Você também pode gostar