Arquivos de Texto - PUC-SP

Propaganda
Pontifícia Universidade Católica de São Paulo
Departamento de Ciência da Computação
Apontamento 15
Maio de 2004
LP: Laboratório de Programação
Prof. ISVega
Arquivos de Texto
CONTEÚDO
15.1 Processamento de Arquivos . . . . . . . . . . .
15.2 Processamento de Arquivos de Texto . . . . .
15.2.1Escrita de Texto COM Filtros . . . . . .
15.2.2Leitura de Texto COM Filtros . . . . . .
15.3 Aplicação: Controle de Estoque . . . . . . . .
15.3.1Criação do Arquivo de Estoque . . . . .
15.3.2Processamento do Arquivo de Estoque
Exercícios . . . . . . . . . . . . . . . . . . . . . . . .
Objetivos
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
3
6
8
9
11
15
• Mostrar como ler e escrever arquivos de texto em
Java.
15.1 Processamento de Arquivos
Uma necessidade comum de programação é a leitura e escrita de arquivos em disco.
As informações armazenadas em um objeto-arquivo ou são codificadas na forma de
bytes (dados) ou na forma de texto (linhas de caracteres).
1
Laboratório de Programação
Maio de 2004
Arquivos Pré-definidos Três objetos-arquivo para armazenagem de textos são automaticamente criados, quando se executa um programa em Java: System.in,
System.out e System.err.
Subsistema java.io Para fazer uso dos mecanismos de processamento de arquivos
em Java, deve-se importar o subsistema (pacote) java.io.
Exemplo 15.1 Para que um objeto da classe Livro tenha acesso aos mecanismos
de processamento de arquivos da Tecnologia Java, a sua classe deverá importar o
pacote java.io (Figura 15.1).
Livro
<<import>>
java.io
Figura 15.1: Importação do pacote java.io (diagrama de classes UML).
Em Java:
import java.io.*;
public class Livro {
// Uso dos mecanismos importados...
}
¨
Textos e Dados Por outro lado, as seqüências de bytes podem ser vistas como
texto ou como dados (estruturados). No primeiro caso, deve-se utilizar instâncias do tipo Reader e Writer. No segundo caso, deve-se usar instâncias do tipo
FilterInputStream e FilterOutputStream.
15.2 Processamento de Arquivos de Texto
Processamento de Texto com Filtros O processamento de arquivos de texto (caracteres unicode) com filtros é feito por objetos da classe BufferedReader e
BufferedWriter. O arquivo, propriamente dito, é representado por objetos das
classes Reader ou Writer.
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-2
Laboratório de Programação
Maio de 2004
15.2.1 Escrita de Texto COM Filtros
O padrão dinâmico da escrita em arquivos de texto filtros pode ser descrito pelo
mapa de execução mostrado na Figura 15.2.
Programa
“dados.txt”
arqTexto : FileWriter
new
dados.txt
arqTexto
texto
new
write
filtro :
BufferedWriter
flush
close
Figura 15.2: Padrão para escrita em arquivos de texto.
Inicialmente, cria-se um contexto de execução que interage diretamente com o arquivo, no caso dados.txt. Este contexto é utilizado para construir o filtro de
acesso ao conteúdo do arquivo. O filtro é um contexto da classe BufferedWriter.
Com a ajuda do filtro, diversas linhas de texto podem ser escritas no arquivo
utilizando-se a operação write(). Este serviço recebe a linha de texto a ser escrita,
repassando-a para o contexto de execução que interage diretamente com o arquivo.
Imediatamente antes de se fechar o filtro (que, por sua vez, provoca o fechamento do
arquivo), deve-se executar o comando flush(), que envia quaisquer linhas de texto
ainda presentes no filtro para o arquivo.
Observa-se que todas as interações com o arquivo e com o filtro devem ser inseridas em uma região de tratamento de exceções (assinaladas como “relâmpagos” em
vermelho na Figura 15.2).
Modelo de Implementação em Java
A Figura 15.3 ilustra um modelo de processamento de arquivos de texto em Java.
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-3
Laboratório de Programação
Maio de 2004
Figura 15.3: Modelo de objetos para escrita de arquivos de texto
(vista do BlueJ).
Um modelo de implementação em Java deste modelo de escrita em arquivos de texto
seria:
hlab/texto/EscritaTextoFiltro.javai≡
hTexto: (escrita com filtro) classes importadasi
public class EscritaTextoFiltro {
public BufferedWriter filtro;
public void escrever() {
hTexto: (escrita com filtro) abertura e criação do filtroi
hTexto: (escrita com filtro) escrita no arquivoi
hTexto: (escrita com filtro) fechamento do arquivoi
}
}
Importação de Classes para Escrita
As seguintes classes são normalmente importadas quando se programa computações com escrita em arquivos de texto:
hTexto: (escrita com filtro) classes importadasi≡
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
Abertura do Arquivo de Texto
O processamento se inicia com a abertura do arquivo de texto e a criação do filtro a
ser utilizado para processar a sua informação:
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-4
Laboratório de Programação
Maio de 2004
hTexto: (escrita com filtro) abertura e criação do filtroi≡
// ABRIR ARQUIVO DE TEXTO E CRIAR FILTRO
try {
FileWriter arqTexto = new FileWriter( "dados.txt" );
filtro = new BufferedWriter( arqTexto );
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
Escrita no Arquivo de Texto
Em seguida, passa-se à escrita de linhas de texto no arquivo. Strings podem ser
escritas com o uso da operação write(). Mudanças de linha no arquivo podem ser
feitas ativando-se a operação newLine():
hTexto: (escrita com filtro) escrita no arquivoi≡
// ESCREVER NO ARQUIVO DE TEXTO
try {
filtro.write( "Isto eh um teste!" );
filtro.newLine();
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
Fechamento do Arquivo de Texto
Finalmente, após a escrita das informações no arquivo, deve-se fechá-lo, para que o
texto não seja perdido:
hTexto: (escrita com filtro) fechamento do arquivoi≡
// ESVAZIAR FILTRO E FECHAR O ARQUIVO DE TEXTO
try {
filtro.flush();
filtro.close();
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-5
Laboratório de Programação
Maio de 2004
15.2.2 Leitura de Texto COM Filtros
Os principais passos de computação envolvidos na leitura de um texto armazenado
em arquivos de texto são apresentados na Figura 15.4.
Programa
“dados.txt”
arqTexto : FileReader
new
arqTexto
dados.txt
new
readLine
filtro :
BufferedReader
texto
close
Figura 15.4: Padrão para leitura de arquivos de texto.
Modelo de Implementação em Java
A Figura 15.5 ilustra um modelo de processamento de arquivos de texto em Java.
Figura 15.5: Modelo de objetos para leitura de arquivos de texto
(vista do BlueJ).
Um modelo de implementação em Java deste modelo de leitura em arquivos de texto
seria:
hlab/texto/LeituraTextoFiltro.javai≡
hTexto: (leitura com filtro) classes importadasi
public class LeituraTextoFiltro {
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-6
Laboratório de Programação
Maio de 2004
public BufferedReader filtro;
public void ler() {
hTexto: (leitura com filtro) abertura e criação do filtroi
hTexto: (leitura com filtro) leitura no arquivoi
hTexto: (leitura com filtro) fechamento do arquivoi
}
}
Importação de Classes para Leitura
As seguintes classes são normalmente importadas quando se programa computações com leitura de arquivos de texto:
hTexto: (leitura com filtro) classes importadasi≡
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileNotFoundException;
Abertura do Arquivo de Texto
O processamento se inicia com a abertura do arquivo de texto e a criação do filtro a
ser utilizado para processar a sua informação:
hTexto: (leitura com filtro) abertura e criação do filtroi≡
// ABRIR ARQUIVO DE TEXTO E CRIAR FILTRO
try {
FileReader arqTexto = new FileReader( "dados.txt" );
filtro = new BufferedReader( arqTexto );
}
catch( FileNotFoundException e ) {
System.out.println( e );
System.exit( 1 );
}
Leitura do Arquivo de Texto
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-7
Laboratório de Programação
Maio de 2004
Em seguida, passa-se à leitura de linhas de texto do arquivo com a ativação da
operação readLine():
hTexto: (leitura com filtro) leitura no arquivoi≡
// LER DO ARQUIVO DE TEXTO
try {
String linha = filtro.readLine();
System.out.println( linha );
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
Fechamento do Arquivo de Texto
Finalmente, após a leitura das informações no arquivo, deve-se fechá-lo:
hTexto: (leitura com filtro) fechamento do arquivoi≡
// FECHAR O ARQUIVO DE TEXTO
try {
filtro.close();
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
15.3 Aplicação: Controle de Estoque
Esta seção cria um arquivo contendo produtos, quantidades e preços unitários, o
qual é posteriormente processado, produzindo um relatório de estoque.
O modelo de classes da aplicação, bem como dos objetos fundamentais, é descrito
na Figura 15.6.
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-8
Laboratório de Programação
Maio de 2004
Figura 15.6: Importação do pacote java.io (diagrama de classes UML).
15.3.1 Criação do Arquivo de Estoque
A criação do arquivo de estoque, denominado estoque.txt, segue o padrão anteriormente descrito para o caso de arquivos de texto.
hlab/estoque/Estoquista.javai≡
hpacotes importados na criação do estoquei
public class Estoquista {
public BufferedWriter filtro = null;
public void cadastrar() {
habrir o arquivo de texto e criar o filtro de escrita do estoquei
hobter as quantidades de produtos e escrever no arquivoi
hesvaziar o filtro e fechar o arquivo de textoi
System.exit(0);
}
}
São os seguintes as classes necessárias para criar o arquivo de estoque:
hpacotes importados na criação do estoquei≡
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
A abertura e criação do filtro de escrita obedece ao padrão:
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-9
Laboratório de Programação
Maio de 2004
habrir o arquivo de texto e criar o filtro de escrita do estoquei≡
// ABRIR ARQUIVO DE TEXTO E CRIAR FILTRO
BufferedWriter filtro = null;
try {
FileWriter arqTexto = new FileWriter( "estoque.txt" );
filtro = new BufferedWriter( arqTexto );
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
A parte principal da criação do arquivo de estoque deve percorrer cada produto e solicitar que o estoquista informe a quantidade atual existente. Inicialmente os produtos e preços unitários são definidos. Em seguida, cria-se um optico:LeitorOptico
para solicitação das quantidades. Uma repetição controlada por contador percorre
cada produto e solicita a quantidade existente. Este valor é convertido para int,
sendo utilizado para montar uma linha, escrita no arquivo de texto:
hobter as quantidades de produtos e escrever no arquivoi≡
// ESCREVER NO ARQUIVO DE TEXTO
try {
String[] produtos = { "Lapis", "Borracha", "Caderno", "Caneta" };
String[] precos = { "0.70", "0.35", "5.00", "1.20" };
LeitorOptico optico = new LeitorOptico();
for( int i = 0; i < produtos.length; i++ ) {
int qtde =
optico.obterInt( "Quantidade de " + produtos[i] + "?");
String linha = produtos[i] + " " + qtde + " " + precos[i];
filtro.write( linha );
filtro.newLine();
}
optico = null;
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
A parte final esvazia o filtro e fecha o arquivo de texto contendo as informações sobre
o estoque atual:
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-10
Laboratório de Programação
Maio de 2004
hesvaziar o filtro e fechar o arquivo de textoi≡
// ESVAZIAR FILTRO E FECHAR O ARQUIVO DE TEXTO
try {
filtro.flush();
filtro.close();
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
O contexto envolvendo o leitor óptico apenas solicita a quantidade de produto disponível no estoque, simulando o dispositivo real de leitura utilizado pelo estoquista:
hlab/estoque/LeitorOptico.javai≡
import javax.swing.JOptionPane;
public class LeitorOptico {
public int obterInt( String pergunta ) {
String linha = JOptionPane.showInputDialog( pergunta );
int n = 0;
try {
n = Integer.parseInt( linha );
}
catch( NumberFormatException e ) {
System.out.println( "Quantidade desconhecida" );
}
return n;
}
}
15.3.2 Processamento do Arquivo de Estoque
O processamento do arquivo de estoque deve ler os valores informados e gerar um
relatório da situação atual dos produtos.
hlab/estoque/Estoque.javai≡
hclasses importadas para o processamento do estoquei
public class Estoque {
public Item[] produtos = new Item[ 100 ];
public void recuperarItens() {
habrir o arquivo de texto e criar o filtro de leitura do estoquei
hcarregar as informações sobre cada produto e gerar o relatórioi
hfechar o arquivo de estoquei
}
hmostrar o relatório do estoquei
}
São os seguintes os arquivos importados para o processamento do estoque:
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-11
Laboratório de Programação
Maio de 2004
hclasses importadas para o processamento do estoquei≡
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
A abertura do arquivo de estoque para leitura, segue o padrão normal visto anteriormente:
habrir o arquivo de texto e criar o filtro de leitura do estoquei≡
// ABRIR ARQUIVO DE TEXTO E CRIAR FILTRO
BufferedReader filtro = null;
try {
FileReader arqTexto = new FileReader( "estoque.txt" );
filtro = new BufferedReader( arqTexto );
}
catch( FileNotFoundException e ) {
System.out.println( e );
System.exit( 1 );
}
A carga de informações do arquivo faz uso do filtro de leitura de linhas. Para cada
linha recuperada, o produto, sua quantidade e preço unitário devem ser determinados. Um contexto denominado analisador da classe StringTokenizer pode ser
utilizado para esta finalidade.
O analisador é criado para cada linha. O serviço nextToken() retorna a cadeia de
caracteres que antecede um separador (o espaço e o terminador de linha são os
separadores normais). No caso deste sistema, cada linha contém três informações
(produto, quantidade e preço) separaradas por um espaço. Por conseguinte três
ativações do serviço nextToken() são utilizadas para recuperar estas informações.
A partir delas, um novo contexto da classe Item é construído, sendo de imediato
inserido na lista produtos, representado o estoque atual:
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-12
Laboratório de Programação
Maio de 2004
hcarregar as informações sobre cada produto e gerar o relatórioi≡
// LER DO ARQUIVO DE TEXTO
Item[] produtos = new Item[ 100 ];
int n = 0;
try {
String linha = filtro.readLine();
while( linha != null ) {
StringTokenizer analisador = new StringTokenizer( linha );
String produto = analisador.nextToken();
hrecuperar um item e inserir na lista de produtosi
linha = filtro.readLine();
}
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
No núcleo da estrutura de repetição controlada por sentinela, deve-se recuperar as
informações de um único item, criar um objeto encapsulando estas informações e
inseri-lo na lista de produtos do estoque:
hrecuperar um item e inserir na lista de produtosi≡
try {
int qtde = Integer.parseInt( analisador.nextToken() );
double preco = Double.parseDouble( analisador.nextToken() );
produtos[n] = new Item( produto, qtde, preco );
n++;
}
catch( NumberFormatException e ) {
System.out.println(
"ERRO no arquivo de entrada: linha ignorada" );
System.out.println( linha );
}
Após a leitura de todas as linhas do arquivo de estoque, ele é fechado:
hfechar o arquivo de estoquei≡
// FECHAR O ARQUIVO DE TEXTO
try {
filtro.close();
}
catch( IOException e ) {
System.out.println( e );
System.exit( 1 );
}
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-13
Laboratório de Programação
Maio de 2004
Por último, a lista de produtos é apresentada, contabilizando-se o valor total de cada
produto disponível:
hmostrar o relatório do estoquei≡
public void gerarRelatorio() {
for( int i = 0; i < produtos.length; i++ ) {
System.out.println( produtos[i] );
}
}
A classe Item modela a estrutura de informações de um item estocado. A estrutura
é composta pelo nome do produto, sua quantidade em estoque e o seu preço unitário. Adicionalmente, uma propriedade de formatação é utilizada no momento da
conversão feita pelo serviço toString():
hlab/estoque/Item.javai≡
import java.text.DecimalFormat;
public class Item {
private String _produto;
private int _quantidade;
private double _preco;
private DecimalFormat _formato;
public Item( String produto, int quantidade, double preco ) {
_produto = produto;
_quantidade = quantidade;
_preco = preco;
_formato = new DecimalFormat( "0.##" );
}
public String toString() {
return _produto + ":" + _quantidade + " a " + _preco + " = " +
_formato.format( (_quantidade * _preco) );
}
}
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-14
Laboratório de Programação
Maio de 2004
E XERCÍCIOS
15.1 M ODELO GERAL DE ESCRITA EM ARQUIVOS DE TEXTO
o programa de escrita em arquivos de dados com filtro:
Tarefa 15.1.1
Crie o projeto ex15.1.
Tarefa 15.1.2
Crie a classe EscritaTextoFiltro.
Tarefa
15.1.3
Crie
escritor.escrever().
o
objeto
escritor
e
15.2 M ODELO GERAL DE LEITURA DE ARQUIVOS DE TEXTO
Implemente e execute
envie
a
mensagem
Implemente e execute
o programa de leitura em arquivos de dados com filtro:
Tarefa 15.2.1
Crie o projeto ex15.2.
Tarefa 15.2.2
Crie a classe LeituraTextoFiltro.
Tarefa 15.2.3
Crie o objeto leitor e envie a mensagem leitor.ler().
15.3 C ONTROLE
DE
E STOQUE
Sobre o sistema de controle de estoque:
Tarefa 15.3.1
Crie o projeto ex15.3.
Tarefa 15.3.2
Implemente o programa do sistema de controle de estoque.
Tarefa 15.3.3
Crie os objetos aldo:Estoquista e bazar:Estoque.
Tarefa 15.3.4
Qual o efeito do processamento da mensagem aldo.cadastrar()?
Tarefa
15.3.5
Qual
o
efeito
do
processamento
das
bazar.recuperarItens() seguida de bazar.gerarRelatorio()?
mensagens
Tarefa 15.3.6 Altere o arquivo Estoque.java de modo a ser apresentado o valor
total estocado (somatória dos valores dos produtos estocados).
OBS: procure utilizar um novo método totalizar(produtos):void que recebe o
array produtos por referência e retorna o cálculo solicitado.
c
Copyright °1998-2004,
Dr. Italo S. Vega
15-15
Download