Streams I - Unisinos

Propaganda
Streams
Profa. Patrícia A. Jaques
[email protected]
Unisinos
Lendo do Console com a classe Scanner
import java.util.Scanner;
public class TestaScanner {
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
System.out.println("Digite um numero:");
String numero = scanner.nextLine();
System.out.println("O numero digitado foi:" + numero);
}
}
Laboratório 2 - Patrícia Jaques
2
Entrada e saída de dados em Java
•
A maioria dos programas precisa acessar e enviar dados externos ao
programa.
•
Os dados de entrada podem ser provenientes de um arquivo em disco,
de um teclado ou de uma conexão em rede.
•
Java permite lidar com todos os tipos de entrada e saída através de
uma abstração conhecida como stream.
arquivo
Uma stream
Programa
Laboratório 2 - Patrícia Jaques
3
Manipulação de Dados em um Computador
•
Armazenamento em array é temporário
–
•
Armazenar dados em memória secundária (persistente)
–
•
•
•
•
dados são perdidos quando programa finaliza a execução
editor de texto
Computador processa informação como 0 e 1
–
bit menor unidade do computador
–
manipulado por circuitos
Programador:
–
incômodo programar em bits
–
trabalham com conjunto de caracteres do computador: letras, números e símbolos
especiais
Conjunto de caracteres:
–
como computador só trabalha com 0 e 1, cada caractere é representado por um padrão
de 0 e 1
–
Byte: 8 bits
Formatos para caracteres:
–
ASCII (American Standard Code for Information Interchange): caracteres representados
por 1 byte
–
UNICODE: caracteres representados por 2 bytes
Laboratório 2 - Patrícia Jaques
4
Tabela ASCII
Laboratório 2 - Patrícia Jaques
5
Arquivo
• Na visão do sistema operacional, um arquivo é conjunto de
bytes.
• A organização dos bytes em um arquivo é uma visão criada
pelo aplicativo.
– arquivo ppt
– arquivo ASCII
– conjunto de registros em um arquivo de banco de dados
• Java vê arquivo como um fluxo seqüencial de bytes
– Cada arquivo acaba com um marcador de fim: que Java avisa ao
programador através de exceção ou do valor devolvido pelo
método que processa (lê) o arquivo.
• Trabalhando com arquivos em Java:
– Abrir o arquivo
– Processar o arquivo (ler seus bytes até o final do arquivo) ou
escrever no arquivo
– Fechar o arquivo
Laboratório 2 - Patrícia Jaques
6
Streams de Leitura
010010101
010101010
010100101
010100101
010101010
10101
Uma stream
J
bytes ou
caracteres
Streams de Escrita
Programa
bytes ou
caracteres
Programa
J
010010101
010101010
010100101
010100101
010101010
10101
Laboratório 2 - Patrícia Jaques
7
Streams são unidirecionais
• O pacote java.io define um grande número de classes para ler e
escrever streams.
– import java.io.*;
• Streams são unidirecionais
– Streams para leitura
– Stream para escrita
• Streams permitem:
– acesso seqüencial dos dados do arquivo:
• programa lê os dados a partir do início do arquivo
• lê todos os dados consecutivamente até encontrar dado procurado ou chegar
no final do arquivo
• Não permite voltar ao início do arquivo para lê-lo novamente: necessário
fechar e reabrir o arquivo.
– acesso aleatório dos dados do arquivo:
• permite reposicionar ponteiro do arquivo (o número que indica a posição do
próximo byte do arquivo a ser lido ou gravado) para voltar ao início do arquivo
ou diretamente a uma outra posição.
Laboratório 2 - Patrícia Jaques
8
Lendo Bytes e Caracteres
Bytes
• As classes InputStream e OutputStream, bem como as
suas subclasses, são usadas para ler e escrever stream
de bytes;
Quando usar: para ler e
escrever dados binários,
Classes abstratas
tais como imagens e sons
InputStream – Ler
OutputStream -
Escrever
• As classes Reader e Writer (e subclasses) são usadas
para ler e escrever streams de caracteres (2 bytes).
Caracteres
Classes abstratas
Reader – Ler
Writer - Escrever
Quando usar: para ler e
escrever dados textuais
Laboratório 2 - Patrícia Jaques
9
Obtendo as propriedades de um arquivo –
class File
import java.io.File;
import java.util.Date;
import java.text.*;
class TestaArquivo {
public static void main (String args []) {
File f = new File ("C:/Documents and Settings/Patricia Jaques/Mes
documents/Cursos/CursoJava/ExerciciosApostila/03_Poo/Circle.java");
System.out.println ("Nome do arquivo: "+f.getName ());
System.out.println ("Caminho: "+f.getPath ()); // retorna diretório denotado pelo nome
System.out.println ("Caminho Absoluto: "+f.getAbsolutePath ()); // consulta SO
System.out.println ("Diretório pai: "+f.getParent ());
System.out.println (f.exists() ? "existe":"não existe");
System.out.println (f.canWrite() ? "pode ser gravado":"não pode ser gravado");
System.out.println (f.canRead() ? "pode ser lido":"não pode ser lido");
System.out.println (f.isDirectory () ? "é diretório":"não é diretório");
DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
Date data = new Date (f.lastModified ());
System.out.println ("Ultima modificação do arquivo: "+df.format (data));
System.out.println ("Tamanho do arquivo: "+f.length ()+ " bytes.");
}
} // da class TestaArquivo
Laboratório 2 - Patrícia Jaques
10
Listando diretórios
import java.io.File;
class ListaDir {
public static void main (String args [ ]) {
String nomeDir = ".";
File f1 = new File (nomeDir);
if (f1.isDirectory ( ))
{
System.out.println ("Diretório "+nomeDir);
String s[ ] = f1.list( );
for (int i=0; i<s.length; i++)
{
File f = new File (s[i]);
System.out.print (s[i]);
if (f.isDirectory ( )) System.out.println (" <dir> ");
else System.out.println (" <file>");
}
}
else System.out.println (nomeDir + " não é um diretório.");
}
} // da class
Laboratório 2 - Patrícia Jaques
11
Trabalhando com Arquivo Texto
Lendo e escrevendo texto
• A plataforma armazena caracteres segundo
convenção Unicode. As classes filhas das classes
Reader e Writer convertem os caracteres Unicode de
e para o formato de caractere usado pela plataforma
(geralmente ASCII-8).
Laboratório 2 - Patrícia Jaques
13
Escrita
Leitura
Hierarquia de Classes de Reader e Writer
PrintWriter
Laboratório 2 - Patrícia Jaques
14
Trabalhando com caracteres – Reader e
Writer
• Reader
• int read()
• int read(char cbuf[])
• int read(char cbuf[], int offset, int length)
• Writer
novas
• void write(int c)
• void write(char cbuf[])
• void write(char cbuf[], int offset, int length)
• void write(String str)
• void write(String str, int off, int len)
Laboratório 2 - Patrícia Jaques
15
FileReader e FileWriter
• FileReader:
– Para ler arquivos textos
– FileReader (File file)
– FileReader (String fileName)
• FileWriter
–
–
–
–
–
Para escrever em arquivos textos
FileWriter (File file)
FileWriter (File file, boolean append)
FileWriter (String fileName)
FileWriter (String fileName, boolean append)
Laboratório 2 - Patrícia Jaques
16
Lendo Arquivos Textos
• Caracteres são armazenados em buffers após serem lidos.
• BufferedReader
– FileReader fr = new FileReader (filename);
– BufferedReader in = new BufferedReader (fr);
– Método “String readLine()”: Retorna a próxima linha de texto do
arquivo;
Laboratório 2 - Patrícia Jaques
17
Lendo linhas de um arquivo texto
import java.io.*;
public class LeArquivo {
public static void main(String args[]) {
String filename = "E:\\aulas\\lab2\\t1.txt";
try {
FileReader fr = new FileReader(filename);
BufferedReader in = new BufferedReader(fr);
String line = in.readLine();
while (line != null) {
System.out.println(line);
line = in.readLine();
}
in.close();
} catch (FileNotFoundException e) {
System.out.println("Arquivo \""+filename+"\" não existe.");
} catch (IOException e) {
System.out.println("Erro na leitura do arquivo " + filename+".");
}
}
}
Laboratório 2 - Patrícia Jaques
19
Método Split
class BuscaPalavrasEmUmaString {
public static void main (String args[ ]) {
String texto = "Isto#é#um#texto#de#teste";
// usando delimitador #
String result[] = texto.split("#");
for (int i=0; i<result.length; i++) {
System.out.println (i+1+": "+result[i]);
}
} // main
} // class
c:\> java BuscaPalavrasEmUmaString
1: Isto
2: é
3: um
4: texto
5: de
6: teste
Laboratório 2 - Patrícia Jaques
20
Exercício 2 – Separando Tokens
•
•
Crie uma classe chamada Book
Esta classe vai ter os seguintes atributos:
–
–
–
–
–
•
String title;
String isbn;
String publisherId;
String url;
float price;
Leia o arquivo Books.txt e guarde os dados de cada linha dentro de um objeto Book. Para
fazer isso:
–
Leia uma linha por vez com o método readLine( ) da classe BuffererReader
•
–
–
Cada linha da tabela é uma linha do arquivo.
Cada coluna do arquivo é uma string da linha separa pelo delimitador ‘|’ (pipe).
•
•
–
•
Para obter esta string use o método split da classe String. Ex:
String result [ ] = line.split(“\\|”);
Cada token do split() vai ser um dado do objeto Book, de acordo com a sua ordem. O primeiro
token vai ser sempre o title e assim por diante:
•
•
•
•
•
•
•
Line = in.readLine();
String title = result[0];
String isbn = result[1];
….
Book b = new Book();
b.setTitle(title);
…
Crie uma array de books (ou vector) para guardar todos os objetos e percorra essa array
imprimindo o conteúdo de seus objetosLaboratório 2 - Patrícia Jaques
21
Não esqueça de importar o pacote java.io.*;
PrintWriter
métodos
construtores
•
•
•
•
•
•
void println (String x)
void println (int x) …
PrintWriter (OutputStream out)
PrintWriter (Writer out) // default=sem flush automático, nem para método
println
PrintWriter (Writer out, boolean autoFlush)
– autoflush == true  dá flush com método println
– só da flush com o método println e não com o caracter /n
converte caractereres UNICODE Java para formato de caracter da plataforma
onde o programa Java está executando
Laboratório 2 - Patrícia Jaques
22
Escrevendo linhas em um arquivo texto
import java.io.*;
class EscreveArquivo
{
public static void main (String args [ ]) {
try {
File f = new File ("MeuArquivo.txt");
FileWriter fr = new FileWriter (f);
PrintWriter out = new PrintWriter (fr);
out.println ("Curso de Java: Arquivo gerado pelo programa.");
out.close();
}
catch (IOException e) {
System.out.println ("Erro ao escrever arquivo.");
}
}
}
Laboratório 2 - Patrícia Jaques
23
Exercício de Agenda de contatos
• O sistema de agenda deve manter uma lista de contatos.
• Um contato padrão tem: nome, e-mail, telefone, endereço e data do
aniversário. Porém o contato pode ser enquadrado como de algum tipo
específico: geral, cliente ou fornecedor. Para fornecedor, é interessante
manter-se um índice de qualidade, pois pode ser necessário ter de
escolher 1 entre vários fornecedores de um mesmo produto. Já para o
cliente, deve-se atribuir uma data da última compra e uma classificação
de fidelidade (ou valores possíveis são: fiel, freqüente, pouco freqüente e
apenas uma vez). Por fim, da categoria geral, não é necessário guardar
mais nenhum dado além dos do contato.
• O programa da agenda deve manter um menu de opções do programa:
incluir contato (acrescenta numa lista de contatos ordenados por nome),
excluir
contato (retirar da lista), listar contatos, consulta dados de um contato e
sair.
• OBS:
– A inclusão de contatos deve acontecer na ordem alfabética pelo campo nome.
Exercício de Agenda de contatos
• Ler e gravar de um arquivo registros de contatos de uma
agenda de contatos. Formato do arquivo:
– <id>;<tipo (0-geral, 1-cliente ou 2-fornecedor>;
<nome>;<telefone>;<email>;<endereço>;<nascimento>
– Para o tipo 1: <fidelidade>;<data ultima compra>
– Para o tipo 2: <classificação>
• Colocar numa lista de contatos. Os contatos podem ser
Geral, Cliente ou Fornecedor
• Colocar controle das seguintes exceções:
–
–
–
–
Arquivo não encontrado
Tipo de contato inválido (diferente de 0, 1 e 2)
Nome deve ter no mínimo duas partículas (nome e sobrenome)
Problemas de conversão de String para os respectivos tipos de
dados.
PARA ENTREGAR ATÉ O GA
Lendo e Escrevendo
Dados Binários
Lendo Bytes e Caracteres
Bytes
• As classes InputStream e OutputStream, bem como as
suas subclasses, são usadas para ler e escrever stream
de bytes;
Quando usar: para ler e
Classes abstratas
InputStream – Ler
OutputStream - Escrever
escrever dados binários,
tais como imagens e sons
• As classes Reader e Writer (e subclasses) são usadas
para ler e escrever streams de caracteres (2 bytes).
Caracteres
Classes abstratas
Reader – Ler
Writer - Escrever
Quando usar: para ler e
escrever dados textuais
Leitura
Hierarquia de Classes de InpuStream e
OutputStream
Escrita
Serialização
Pular para posição no texto
A Classe InputStream – abstract class
A Classe OutputStream – abstract class
BufferedOutputStream
FileInputStream e FileOutputStream
import java.io.*;
public class CopiaArquivo {
public static void main(String arg[]) throws IOException {
FileInputStream in = new FileInputStream("CopiaArquivo.java");
// sobrescreve arquivo se ele já existe
FileOutputStream
out
=
new
FileOutputStream
"Copia de CopiaArquivo.java");
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
}
(
FileOutputStream (String name, boolean append) // escreve no final do arquivo
FileOutputStream (File file)
FileOutputStream (File file, boolean append)
Bufferização
• Assim como temos BufferedReader e BufferedWirter para
bufferização de arquivos textos, quando estamos trabalhando
com arquivos binários, podemos usar as classes:
– BufferedInputStream
– BufferedOutputStream
• Essas classes mantém os dados a serem escritos (no caso da
BufferedOutputStream) ou lidos (BufferedOutputStream) em
um buffer. Assim, o programa só vai realizar uma nova
operação física de entrada ou saída de dados quando o buffer
estiver vazio (no caso de leitura) ou cheio (no caso de saída).
• Em qualquer momento é possível forçar a saída (a gravação em
arquivo) com o método flush( ) da classe
BufferedOutputStream.
import java.io.*;
public class BufferInputOutput {
public static void main(String arg[]) {
try {
FileInputStream in = new FileInputStream("prim.txt");
BufferedInputStream bin = new BufferedInputStream(in);
// sobrescreve arquivo se ele já existe
FileOutputStream out = new FileOutputStream("Copia.txt");
BufferedOutputStream bout = new BufferedOutputStream(out);
int c;
while ((c = bin.read()) != -1)
bout.write(c);
bin.close();
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Exercícios
• Implemente o comando type do MS-DOS.
• Voce deve fornecer ao seu programa a seguinte linha
de execução:
– java Type nomeArquivo
• Ele mostrará na tela o conteúdo do arquivo
• Antes de tentar abrir o arquivo, teste com a classe
File se o arquivo existe, e avise o usuário caso ele
não exista
PrintStream
• Ela grava em formato textual vários tipos de dados
do java: boolean, char, int, etc
• Não gera exceção IOException
• Dados são gravados (flush) automaticamente a cada
print
• É o tipo da variável System.out.
PrintStream
import java.io.*;
class PrintStreamDemo {
public static void main(String args[]){
try {
FileOutputStream out = new FileOutputStream("myfile.txt");
PrintStream ps = new PrintStream(out);
ps.println ("This data is written to a file:");
System.out.println ("Write successfully");
ps.close();
}
}
}
catch (Exception e){
System.out.println ("Error in writing to file");
}
Arquivos de Acesso Randômico
Acesso Seqüencial x Acesso aleatório
• aceso seqüencial dos dados do arquivo:
– programa lê os dados a partir do início do arquivo
– lê todos os dados consecutivamente até encontrar dado
procurado ou chegar no final do arquivo
– Não permite voltar ao início do arquivo para lê-lo
novamente: necessário fechar e reabrir o arquivo.
– não é possível modificar um dado apenas do arquivo. O
arquivo deve ser totalmente sobrescrito.
• acesso aleatório dos dados do arquivo:
– permite reposicionar ponteiro do arquivo (o número que
indica a posição do próximo byte do arquivo a ser lido ou
gravado) para voltar ao início do arquivo ou diretamente a
uma outra posição.
– é possível modificar um dado apenas: interessante exigir
que todos os registros tenham o mesmo tamanho
Laboratório 2 - Patrícia Jaques
36
Arquivos de acesso randômico
import java.io.*;
class ArquivoAcessoRandomico {
public static void main (String args []) throws java.io.IOException {
RandomAccessFile raf = new RandomAccessFile ("Raf.txt", "rw");
raf.writeBytes ("Escrevendo a primeira linha.\n");
raf.writeBytes ("Escrevendo a segunda linha.\n");
raf.seek (0);
String s = raf.readLine ();
System.out.println ("Primeira linha no texto: "+s);
raf.seek (raf.length()); // vai para o final do arquivo
raf.writeBytes ("Escrevendo a última linha.\n");
}
}
// se arquivo já existe, substitui a partir da posição 0
Laboratório 2 - Patrícia Jaques
37
RandomAccessFile
• Métodos interessantes:
– int read () - retorna byte lido como inteiro. Retorna -1
quando chegou no final do arquivo.
– void write (int) – grava byte no arquivo
– long length ( ) – retorna nro. de bytes no arquivo
Serialização
Lendo e Escrevendo objetos em arquivos
Armazenando objetos em arquivos
import java.io.*;
class Serializacao {
public static void main (String args [ ]) {
Pessoa p = new Pessoa ("Homem Aranha", 5, 8, 1937);
File f = new File ("ArqSerializacao.arq");
gravaObjeto (f, p);
Pessoa p2 = (Pessoa) leObjeto (f);
System.out.println ("Foi armazendo o objeto pessoa com os valores:");
System.out.println ("Nome: "+p2.getNome()+" \nData:
"+p2.getData());
}
}
Armazenando objetos em arquivos
private static void gravaObjeto (File f, Object o) {
try
{
FileOutputStream fos = new FileOutputStream (f);
ObjectOutputStream os = new ObjectOutputStream (fos);
os.writeObject (o);
os.close ();
} catch (IOException e) {
System.out.println ("Erro ao gravar objeto.");
}
}
Armazenando objetos em arquivos
private static Object leObjeto (File f) {
Object o = null;
try
{
FileInputStream fos = new FileInputStream (f);
ObjectInputStream os = new ObjectInputStream (fos);
o = os.readObject ();
os.close ();
}
catch (IOException e) {
System.out.println ("Erro ao abrir arquivo.");
}
catch (ClassNotFoundException ce) {
System.out.println ("Objeto não encontrado.");
}
return o;
} } // da class Serializacao
Armazenando objetos em arquivos
class Pessoa implements Serializable
{
String nome;
Data d;
public Pessoa (String nome, int dia, int mes, int ano)
{
this.nome = nome;
d = new Data (dia, mes, ano);
}
public String getNome ()
{
return nome;
}
public String getData ()
{
return d.getData ();
}
} // da class Pessoa
Armazenando objetos em arquivos
class Data implements Serializable
{
int dia;
int mes;
int ano;
public Data (int dia, int mes, int ano)
{
this.dia = dia;
this.mes = mes;
this.ano = ano;
}
public String getData ()
{
return dia+"/"+mes+"/"+ano;
}
} // da class Data
Exercícios
•
•
•
•
Crie um programa que simule uma base de dados, armazenando
registros de produtos em um arquivo.
Um registro vai ser um objeto do tipo Book (que implementa a
interface Serializable) que vimos no exercício anterior.
O seu programa permite ler e armazenar os objetos Book que estão
contidos no Vector e que foram lidos do arquivo Books.txt.
Voce terá de:
– No programa anterior:
•
• Criar um método que grave todos os objetos que estão dentro
de um vector;
• Criar método que leia todos os objetos
Observação:
– O método readObject() não retorna null quando ele atinge o fim do
arquivo. Quando chegou no final do arquivo, ele gera uma exceção do tipo
java.io.EOFException.
– Assim, para ler todos os objetos do arquivo, você tem duas soluções:
• Guarde o número de objetos gravados no arquivo numa
variável e depois utilize um for para ler os objetos do arquivo.
• Trate a exceção EOFException para saber quando chegou no
final do arquivo.
Download