unidade viii dados em javawiki.cbatista.net/lib/exe/fetch.php/unidadeviii1_2_comserializacao.pdf ·...

Post on 10-Aug-2020

0 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Unidade VIII – Persistência de

Dados em Java

Linguagem de Programação I

Universidade Federal da Paraíba

Centro de Informática

Departamento de Informática

Daniela Coelho Batista Guedes Pereira ©

2

Unidade VIII

Conteúdo abordado:

Streams

Arquivos

3

Streams

Abstrações de java para lidar com o fluxo de dados

Fluxos de dados ocorrem quando:

um programa lê do teclado;

um dado é enviado por uma conexão de rede;

dados são lidos ou escritos em arquivos.

Toda movimentação de bytes em java se dá

através de streams.

A vantagem de se unificar todas essas fontes de

E/S é que não é necessário saber para onde (ou

como) estão indo os bytes ou de onde eles vêm.

4

Streams

Um stream é como um cano por onde fluem bytes.

Este cano pode estar conectado a uma fonte de

bytes (um arquivo, uma conexão de rede, dados

oriundos da entrada padrão) e os dados serão lidos

(ou escritos da mesma forma).

Um stream de entrada

5

Streams

Independente do tipo ou de onde a informação

esteja fluindo, o algoritmo para se trabalhar com

streams é sempre o mesmo:

Leitura Escrita

Abra o stream Abra o stream

Enquanto existirem dados Enquanto existirem dados

leia dado escreva dado

Fechar stream Fechar stream

As classes que implementam streams em java

fornecem métodos para ler do stream, ir para

algum ponto do stream e fechar um stream.

6

Streams

O package java.io contém um conjunto de streams

de entrada e saída que os programas podem

utilizar para ler e escrever dados.

As superclasses abstratas InputStream e

OutputStream são responsáveis por definirem o

comportamento dos streams de entrada e saída.

Existem várias subclasses de InputStream e

OutputStream que implementam tipos específicos

de streams de entrada e saída.

7

Hierarquiajava.lang.Object

java.io.File

Java.io.ByteArrayInputStream

java.io.RamdomAccessFile Java.io.OutputStream Java.io.InputStream java.io.StreamTokenizer

Java.io.SequenceInputStream

Java.io.ObjectInputStream

Java.io.FileInputStream

Java.io.PipedInputStream

Java.io.FilterInputStream

Java.io.ByteArrayOutputStream

Java.io.DataInputStream

Java.io.BufferedInputStream

Java.io.PushBackInputStream

Java.io.LineNumberInputStream

Java.io.PipedOutputStream

Java.io.FileOutputStream

Java.io.FilterOutputStream

Java.io.DataOutputStream

Java.io.BufferedOutputStream

Java.io.PrintStream

Java.io.ObjectOutputStream

8

Subclasses de InputStream e OutputStream

FileInputStream: Lê dados de um arquivo.

FileOutputStream: Escreve dados em um arquivo.

PipedInputStream: Implementa os componentes de

entrada de um pipe (canais de comunicação

sincronizados entre threads). O thread lê

informações do pipe via um PipedInputStream.

PipedOutputStream: Implementa os componentes

de saída de um pipe. Um thread envia dados para

outro thread via um PipedOutputStream.

9

Subclasses de InputStream e OutputStream

ByteArrayInputStream: Lê dados de um array de

bytes da memória.

ByteArrayOutputStream: Escreve dados em um

array de bytes da memória.

SequenceInputStream: Concatena múltiplos

streams de entrada em um único stream de

entrada.

10

Subclasses de InputStream e OutputStream

ObjectInputStream: Habilita um programa a ler

objetos serializados, através do método

readObject. O tipo de retorno deste método é

Object, portanto objetos desserializados devem ser

convertidos para o seu tipo real.

ObjectOutputStream: Habilita um programa a

gravar objetos serializados, através do método

writeObject

11

Subclasses de FilterInputStream e FilterOutputStream

DataInputStream: Habilita um programa a ler dados

no formato binário de um InputStream. Lê os tipos

de dados primitivos de java, independente do

formato da máquina. Métodos desta classe:

read, readBoolean, readByte, readChar, readDouble,

readFloat, readInt, readLine, readLong, readShort,

readUTF, readUnsignedByte, readUnsignedShort, etc.

12

Subclasses de FilterInputStream e FilterOutputStream

DataOutputStream: Habilita um programa a

escrever dados no formato binário em um

OutputStream. Lê os tipos de dados primitivos de

java, independente do formato da máquina.

Métodos desta classe:

flush, size, write, writeBoolean, writeByte, writeBytes,

writeChar, writeChars, writeDouble, writeFloat, writeInt,

writeLong, writeShort, writeUTF, etc.

13

Outras Classes do Package java.io

File: Representa um arquivo. Habilita programas

para obter informações sobre um arquivo ou

diretório.

RandomAccessFile: Representa um arquivo de

acesso randômico.

StreamTokenizer: Divide o conteúdo de um stream

de texto de um arquivo texto de entrada em tokens

(menor unidade reconhecida por um parser -

palavras, símbolos, etc.)

14

Utilizando Streams para Ler e Escrever via E/S Padrão

Em java, as fontes de dados Teclado e Vídeo são

dois streams colocados nas variáveis de classe in

(objeto da classe InputStream) e out (objeto da

classe PrintStream) de System.

PrintStream

print(String s) - Envia um string para o stream. Se o

dado não for um string mas for um tipo básico ou

um objeto que possua um método toString ele será

convertido automaticamente.

println(String s) - idêntico ao anterior, porém envia

um “\n” no final.

15

Utilizando Streams para Ler e Escrever via E/S Padrão

InputStream

read( ) - Lê um byte do stream. Esse byte pode

significar muitas coisas: o primeiro byte de um

caracter unicode, o primeiro byte do primeiro

caracter de um string, o byte mais significativo de

um inteiro, etc.

16

Utilizando Streams para Ler e Escrever em Arquivos

Se os seus dados forem usados somente pelo

programa Java que o gerou

Os objetos devem ser salvos, através do mecanismo de

serialização.

Se os seus dados forem usados por outros

programa

Grave os dados em arquivos binários ou texto

17

Utilizando Streams para Ler e Escrever em Arquivos

Esquema de Serialização de Objetos

Para os objetos serem serializáveis a sua classe

tem que implementar a interface Serializable.

As variáveis estáticas não são serializadas.

18

Utilizando Streams para Ler e Escrever em Arquivos

A interface Serializable não possui nenhum método a

implementar. Sua única finalidade é anunciar que a

classe que está implementando pode ser serializada

Quando um objeto é serializado, todos os objetos que

ele referencia nas variáveis de instância também são

serializados, desde que todas as classes implementem

Serializable.

Marque uma variável de instância de uma classe com

a palavra-chave transient se quiser que a serialização

a ignore. Ela será restaurada com nulos (para tipos

referência) ou valores padrão (para tipos primitivo).

19

Utilizando Streams para Ler e Escrever em Arquivos

Esquema de Desserialização de Objetos: Restaurando um

objeto

20

public void setupLer() {

//Abre arquivo para leitura

try {

fileStream = new FileInputStream("cliente.ser");

input = new ObjectInputStream(fileStream);

}

catch (EOFException eof) {

continua = false;

}

catch (IOException e) {

System.err.println("Falha na Abertura do

Arquivo para Leitura\n" +

e.toString());

System.exit(1);

}

}

Rotinas Importantes

21

public void readRecords() {

//Carrega todo o conteúdo do arquivo na Coleção cadcel

try {

while (moreRecords) {

cadcel.add((Agenda)(input.readObject()));

}

} catch (EOFException eof) {

moreRecords = false;

} catch (IOException e) {

System.err.println("Erro durante leitura do

arquivo\n" + e.toString());

System.exit(1);

}catch(ClassNotFoundException c){

System.err.println("Erro durante leitura do

arquivo - Objeto Inválido\n"

+ c.toString());

}

}

Rotinas Importantes

22

public void cleanupLer() {

//Fechar o arquivo, após ter sido descarregado na coleção

try {

input.close();

} catch (IOException e) {

System.err.println("Falha no Fechamento do

Arquivo durante Leitura\n"

+ e.toString());

System.exit(1);

}

dispose(); //libera os recursos

}

Rotinas Importantes

23

public void setupGravar() {

//Abre arquivo para gravar

try{

output = new ObjectOutputStream(new

FileOutputStream("cliente.ser", false));

} catch (IOException e) {

System.err.println("Falha na Abertura do Arquivo

para Gravação\n" +

e.toString());

System.exit(1);

}

}

Rotinas Importantes

public FileOutputStream(File file, boolean append) throws FileNotFoundException :Cria um arquivo output stream para gravar em um arquivo representado pelo objeto File .

public ObjectOutputStream(OutputStream out) throws IOException :

Cria um ObjectOutputStream que escreve em um OutputStream específico.

24

public void addRecords() {

//Carrega toda a coleção no arquivo

try {

for (Agenda a : cadcel) {

output.writeObject(a);

}

} catch (IOException e) {

System.err.println("Erro durante gravação no

arquivo\n" + e.toString());

System.exit(1);

}

}

Rotinas Importantes

25

public void cleanupGravar() {

//Fechar o arquivo, após todos os objetos terem sido gravados

try {

output.flush();

output.close();

} catch (IOException e) {

System.err.println("Falha no Fechamento do

Arquivo – Durante

Gravação!!\n" + e.toString());

System.exit(1);

}

dispose(); //libera os recursos

}

Rotinas Importantes

26

import javax.swing.*;

import javax.swing.border.*;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

// Grava dados oriundo do teclado em um arquivo binário sequencial

public class CriaArqSeq extends JFrame{

private JButton jButton1,jButton2;

private JLabel jLabel1, jLabel2, jLabel3,jLabel4;

private JPanel jPanel1;

private JTextField jTextField1, jTextField2;

private JTextField jTextField3, jTextField4;

// habilita saída de dados para um arquivo

private DataOutputStream output;

public CriaArqSeq() { //construtor

super("Grava Arquivo de Contas");

setup();

initComponents();

}

... //continua

27

public void setup(){

//Abre arquivo

try{

output = new DataOutputStream(

new FileOutputStream("cliente.dat",true));

}catch(IOException e){

System.err.println("Falha na Abertura do

Arquivo\n" + e.toString());

System.exit(1);

}

}

... //continua

28

//envia dados para o arquivo, limpa o

// frame, e fecha o arquivo

public void cleanup(){

if(!jTextField1.getText().equals(""))

addRecord();

try{

output.flush();

output.close();

}catch (IOException e){

System.err.println("Falha no Fechamento do

Arquivo\n" + e.toString());

System.exit(1);

}

}

... //continua

29

//Grava dados no arquivo

public void addRecord(){

int acct = 0;

double d;

acct = (new Integer(jTextField1.getText())).intValue();

try{

if (acct > 0){

output.writeInt(acct);

output.writeUTF(jTextField2.getText());

output.writeUTF(jTextField3.getText());

d = (new Double(jTextField4.getText())).doubleValue();

output.writeDouble(d);

}

}catch(IOException e){

System.err.println("Erro durante gravação no arquivo\n" +

e.toString());

System.exit(1);

}

//Limpa os TextFields

jTextField1.setText(""); jTextField2.setText("");

jTextField3.setText(""); jTextField4.setText("");

}

... //continua

30

//trata os eventos dos botões

private void

jButton1ActionPerformed(java.awt.event.ActionEvent evt)

{

addRecord();

}

private void

jButton2ActionPerformed(java.awt.event.ActionEvent evt)

{

cleanup(); //grava dados, fecha arquivo

dispose(); //libera os recursos

System.exit(0);

}

... //continua

31

//monta a interface

private void initComponents() {

jPanel1 = new JPanel();

jLabel1 = new JLabel();

jTextField1 = new JTextField();

jLabel2 = new JLabel();

jTextField2 = new JTextField();

jLabel3 = new JLabel();

jTextField3 = new JTextField();

jLabel4 = new JLabel();

jTextField4 = new JTextField();

jButton1 = new JButton();

jButton2 = new JButton();

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

jPanel1.setLayout(new GridLayout(5, 2));

jLabel1.setFont(new Font("Tahoma", 0, 14));

jLabel1.setText("Conta:");

jLabel1.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel1);

... //continua

32

//monta a interface (cont.)

jTextField1.setFont(new Font("Tahoma", 0, 14));

jTextField1.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField1);

jLabel2.setFont(new Font("Tahoma", 0, 14));

jLabel2.setText("Nome:");

jLabel2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel2);

jTextField2.setFont(new java.awt.Font("Tahoma", 0, 14));

jTextField2.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField2);

jLabel3.setFont(new Font("Tahoma", 0, 14));

jLabel3.setText("Sobrenome:");

jLabel3.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel3);

jTextField3.setFont(new Font("Tahoma", 0, 14));

jTextField3.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField3);

... //continua

33

//monta a interface (cont.)

jLabel4.setFont(new Font("Tahoma", 0, 14));

jLabel4.setText("Saldo:");

jLabel4.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel4);

jTextField4.setFont(new Font("Tahoma", 0, 14));

jTextField4.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField4);

jButton1.setFont(new Font("Tahoma", 0, 14));

jButton1.setText("Gravar");

jButton1.setActionCommand("Next");

jButton1.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jButton1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent evt) {

jButton1ActionPerformed(evt);

}

});

jPanel1.add(jButton1);

... //continua

34

//monta a interface (cont.)

jButton2.setFont(new Font("Tahoma", 0, 14));

jButton2.setText("Sair");

jButton2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jButton2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent evt) {

jButton2ActionPerformed(evt);

}

});

jPanel1.add(jButton2);

GroupLayout layout = new GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(Alignment.LEADING)

.addGap(0, 400, Short.MAX_VALUE)

.addGroup(layout.createParallelGroup

(GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(0, 118, Short.MAX_VALUE)

.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE,

GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addGap(0, 118, Short.MAX_VALUE)))

);

35

//monta a interface (cont.)

layout.setVerticalGroup(

layout.createParallelGroup(GroupLayout.Alignment.LEADING)

.addGap(0, 300, Short.MAX_VALUE)

.addGroup(layout.createParallelGroup(

GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(0, 92, Short.MAX_VALUE)

.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE,

GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addGap(0, 93, Short.MAX_VALUE)))

);

pack();

} //fim do método initComponents

36

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new CriaArqSeq().setVisible(true);

}

});

}

} //fim da classe CriaArqSeq

37

import javax.swing.*;

import javax.swing.border.*;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

//Lê dados oriundo de um arquivo binário e mostra em uma janela

public class LerArqSeq extends JFrame{

private JButton jButton1,jButton2;

private JLabel jLabel1, jLabel2, jLabel3,jLabel4;

private JPanel jPanel1;

private JTextField jTextField1, jTextField2;

private JTextField jTextField3, jTextField4;

//arquivo de onde os dados serão lidos

private DataInputStream input;

private boolean moreRecords = true;

public LerArqSeq() { //construtor

super(“Ler Arquivo de Contas");

setup();

initComponents();

}

... //continua

38

public void setup(){

//Abre arquivo

try{

input = new DataInputStream(

new FileInputStream("cliente.dat"));

}catch(IOException e){

System.err.println("Falha na Abertura do

Arquivo\n" + e.toString());

System.exit(1);

}

}

... //continua

39

//fecha o arquivo

public void cleanup(){

try{

input.close();

}catch (IOException e){

System.err.println("Falha no Fechamento do

Arquivo\n" + e.toString());

System.exit(1);

}

}

... //continua

40

//Ler dados do arquivo

public void readRecord(){

int account;

String first, last;

double balance;

try{

account = input.readInt();

first = input.readUTF();

last = input.readUTF();

balance = input.readDouble();

jTextField1.setText(String.valueOf(account));

jTextField2.setText(String.valueOf(first));

jTextField3.setText(String.valueOf(last));

jTextField4.setText(String.valueOf(balance));

}catch(EOFException eof){

moreRecords = false;

}

catch(IOException e){

System.err.println("Erro durante leitura do arquivo\n" +

e.toString());

System.exit(1);

}

}

... //continua

41

//trata os eventos dos botões

private void

jButton1ActionPerformed(java.awt.event.ActionEvent evt)

{

readRecord();

}

private void

jButton2ActionPerformed(java.awt.event.ActionEvent evt)

{

cleanup(); //fecha arquivo

dispose(); //libera os recursos

System.exit(0);

}

... //continua

42

//monta a interface

private void initComponents() {

jPanel1 = new JPanel();

jLabel1 = new JLabel();

jTextField1 = new JTextField();

jLabel2 = new JLabel();

jTextField2 = new JTextField();

jLabel3 = new JLabel();

jTextField3 = new JTextField();

jLabel4 = new JLabel();

jTextField4 = new JTextField();

jButton1 = new JButton();

jButton2 = new JButton();

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

jPanel1.setLayout(new GridLayout(5, 2));

jLabel1.setFont(new Font("Tahoma", 0, 14));

jLabel1.setText("Conta:");

jLabel1.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel1);

... //continua

43

//monta a interface (cont.)

jTextField1.setFont(new Font("Tahoma", 0, 14));

jTextField1.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField1);

jLabel2.setFont(new Font("Tahoma", 0, 14));

jLabel2.setText("Nome:");

jLabel2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel2);

jTextField2.setFont(new java.awt.Font("Tahoma", 0, 14));

jTextField2.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField2);

jLabel3.setFont(new Font("Tahoma", 0, 14));

jLabel3.setText("Sobrenome:");

jLabel3.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel3);

jTextField3.setFont(new Font("Tahoma", 0, 14));

jTextField3.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField3);

... //continua

44

//monta a interface (cont.)

jLabel4.setFont(new Font("Tahoma", 0, 14));

jLabel4.setText("Saldo:");

jLabel4.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jLabel4);

jTextField4.setFont(new Font("Tahoma", 0, 14));

jTextField4.setBorder(newSoftBevelBorder(BevelBorder.RAISED));

jPanel1.add(jTextField4);

jButton1.setFont(new Font("Tahoma", 0, 14));

jButton1.setText(“Next");

jButton1.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jButton1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent evt) {

jButton1ActionPerformed(evt);

}

});

jPanel1.add(jButton1);

... //continua

45

//monta a interface (cont.)

jButton2.setFont(new Font("Tahoma", 0, 14));

jButton2.setText("Sair");

jButton2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

jButton2.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent evt) {

jButton2ActionPerformed(evt);

}

});

jPanel1.add(jButton2);

GroupLayout layout = new GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(Alignment.LEADING)

.addGap(0, 400, Short.MAX_VALUE)

.addGroup(layout.createParallelGroup

(GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(0, 118, Short.MAX_VALUE)

.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE,

GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addGap(0, 118, Short.MAX_VALUE)))

);

46

//monta a interface (cont.)

layout.setVerticalGroup(

layout.createParallelGroup(GroupLayout.Alignment.LEADING)

.addGap(0, 300, Short.MAX_VALUE)

.addGroup(layout.createParallelGroup(

GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(0, 92, Short.MAX_VALUE)

.addComponent(jPanel1, GroupLayout.PREFERRED_SIZE,

GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)

.addGap(0, 93, Short.MAX_VALUE)))

);

pack();

} //fim do método initComponents

... //continua

47

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new LerArqSeq().setVisible(true);

}

});

}

} //fim da classe LerArqSeq

top related