Stream – Fluxo I/OManipulação de arquivos binários
Capítulo 10
Stream – Fluxo I/O Introdução Principais Exceptions Arquivos binários
java.io.InputStream java.io.FileInputStream java.io.ByteArrayInputStream java.io.OutputStream java.io.FileOutputStream java.io.ByteArrayOutputStream
Arquivos de acesso randômico
2
Introdução O pacote java.io
Contém classes responsáveis pelo acesso e gravação de dados em formato texto ou formato binário “stream” em arquivos ou outras fontes de dados.
As principais categorias de manipuladores são:○ InputStream e Outputstream – Arquivos binários○ Reader e Writer – Arquivos texto
3
Principais Exceptions
4
IOExceptiongetMessage() : StringprintStackTrace() : void
FileNotFoundExceptiongetMessage() : StringprintStackTrace() : void
EOFExceptiongetMessage() : StringprintStackTrace() : void
Principais Exceptions Principais exceções:
FileNotFoundExceptionOcorre quando a aplicação tenta abrir para leitura um arquivo inexistente
EOFExceptionDisparado pela maioria dos métodos da classe RandomAccessFile quando tenta-se realizar a leitura de bytes após o final do arquivo.
IOExceptionRepresenta qualquer falha ao realizar operações de leitura, escrita ou manipulação de arquivos
5
Arquivos binários Arquivos binários são arquivos que contém informações
ilegíveis por editores de texto comuns.
Exemplos de arquivos binários são MP3, JPEGs, AVIs, DOCs, etc.
Nestes arquivos, cada conjunto de 8 bits (1 byte) representa uma informação que não é interpretada como um caractere do alfabeto e precisam de softwares específicos para reconhecer e interpretar o seu formato.
O pacote java.io possui classes utilitárias que permitem a leitura e gravação de bytes provenientes de arquivos e outras fontes de dados binários.
6
Arquivos binários
7
[Abstract]InputStream
read() : intread(byte[]) : intread(byte[], int, int) : intskip(long) : longavailable() : intclose() : voidmark(int) : voidmarkSupported() : booleanreset() : void
[Abstract]OutputStream
write(int) : voidwrite(byte[]) : voidwrite(byte[], int, int) : voidflush() : voidclose() : void
FileOutputStream
FileOutputStream(String)FileOutputStream(File)
FileInputStream
FileInputStream(String)FileInputStream(File)
ByteArrayInputStreamByteArrayInputStream(byte[])
ByteArrayOutputStreamtoByteArray() : byte[]
RandomAccessFile
RandomAccessFile(String, String)RandomAccessFile(File, String)readBoolean() : booleanreadByte() : bytereadShort() : shortreadChar() : charreadInt() : intreadLong() : longreadFloat() : floatreadDouble() : doublewriteBoolean(boolean) : voidwriteByte(int) : voidwriteShort(int) : voidwriteChar(int) : voidwriteInt(int) : voidwriteLong(long) : voidwriteFloat(float) : voidwriteDouble(double) : void
Arquivos binários java.io.InputStream
Classe abstrata que representa alguma fonte de dados binária.
java.io.OutputStream Classe abstrata que representa
algum destino de dados binários.
java.io.FileInputStream Representa algum arquivo de
onde podemos ler dados byte a byte.
java.io.FileOutputStream Representa algum arquivo onde
podemos armazenar dados byte a byte.
java.io.ByteArrayInputStream Representa um montante de dados em
memória de onde podemos ler dados byte a byte.
java.io.ByteArrayOutputStream Representa um montante de dados em
memória onde podemos armazenar dados byte a byte.
java.io.RandomAccessFile Representa um arquivo binário com
formato pré-definido pelo programador. Útil para armazenamento e leitura de dados de tamanho fixo.
8
java.io.InputStream Um InputStream (também chamado de stream de leitura)
representa um montante de informações binárias enfileirados de onde podemos capturar seus dados byte a byte.
Uma instância da classe InputStream possui um posicionador apontando para algum de seus bytes.
A cada leitura realizada o posicionador captura o byte e avança para o próximo, tornando-o disponível para leitura.
9
Ý w ¦ ÿ À ° í Ù i › ¦ Û Y ô ± ê # ø I ? @ ¶ k › $ ð »� ¼ ƒ ‡� ... æ Ø † 3
java.io.InputStream int read()
Realiza a leitura do byte da vez retornando um número inteiro entre 0 e 255 e avança para o próximo byte.
Caso o posicionador estiver apontando para depois do último byte, este método retorna o valor -1.
10
java.io.InputStreamInputStream input = new FileInputStream(“C:\\foto.jpg”);
byte primeiroByte = (byte) input.read();byte segundoByte = (byte) input.read();byte terceiroByte = (byte) input.read();. . . . . .
11
Ý w ¦ ÿ À ° í Ù i › ¦ Û Y ô ± ê # ø I ? @ ¶ k › $ ð »� ¼ ƒ ‡� ... æ Ø † 3
Alguma implementação de InputStream
java.io.InputStreamInputStream input = new ByteArrayInputStream(stream);byte byteDaVez;
/* Exibe todos os bytes, um de cada vez. */while ((byteDaVez = (byte) input.read()) > -1) {
System.out.println(byteDaVez);}
12
Ý w ¦ ÿ À ° í Ù i › ¦ Û Y ô ± ê # ø I ? @ ¶ k › $ ð »� ¼ ƒ ‡� ... æ Ø † 3
Alguma implementação de InputStream
java.io.InputStream int read(byte[])
Principal método da classe InputStream.
Realiza a leitura de diversos bytes de uma só vez armazenando-os no array especificado.
Após realizar a leitura este método retorna um número inteiro informando quantos bytes foram realmente lidos.
13
java.io.InputStreamInputStream input = new FileInputStream(“C:\\foto.jpg”);byte[] dados = new byte[20];
/* Tenta realizar a leitura dos próximos 20 bytes. */int quant = input.read(dados);
System.out.println(“Foram lidos ” +quant + “ bytes do stream);
14
Ý w ¦ ÿ À ° í Ù i › ¦ Û Y ô ± ê # ø I ? @ ¶ k › $ ð »� ¼ ƒ ‡� ... æ Ø † 3
java.io.InputStreamInputStream input = new FileInputStream(“C:\\foto.jpg”);byte[] dados = new byte[1024];int comp;
/* Lê todos os bytes, 1024 por vez. */while ((comp = input.read(dados)) > -1) {
/* Exibe os bytes lidos */for (int i = 0; i < comp; i++) {
System.out.println(dados[i]);}
}
15
java.io.InputStream int read(byte[], int, int)
Realiza a leitura de diversos bytes de uma só vez armazenando-os no array especificado e nas posições especificadas.
Após realizar a leitura este método retorna um número inteiro informando quantos bytes foram realmente lidos.
16
java.io.InputStream long skip(long)
Avança o posiciondor de leitura sem capturar nenhuma informação do stream.
InputStream input = new FileInputStream(“C:\\plan1.xls”);byte[] stream = new byte[35];
input.read(stream); /* Lê 35 bytes. */input.skip(20); /* “Pula” 20 posições. */input.read(stream); /* Lê mais 35 bytes. */
17
java.io.InputStream int available()
Tenta obter a quantidade de bytes disponíveis para leitura de um stream.
Método não confiável em algumas implementações.
InputStream input = new FileInputStream(“C:\\plan1.xls”);int quant = input.available();
System.out.println(“Existem aproximadamente” + quant +“ bytes disponíveis para leitura.”);
18
java.io.InputStream void close()
Encerra o stream de entrada liberando o recurso (arquivo ou outra origem de dados) tornando-o disponível para utilização por outros programas do sistema operacional.
Este método deve ser executado sempre que terminarmos a utilização do stream.
InputStream input = new FileInputStream(“C:\\plan1.xls”);. . .. . .input.close();
19
java.io.InputStream void reset()
Move o posiciondor de leitura de volta ao início do stream ou até a marca de leitura estabelecida pelo método mark(int).
InputStream input = new FileInputStream(“C:\\plan1.xls”);byte[] stream = new byte[.....];
input.read(stream); /* Lê alguns bytes. */input.reset(); /* Volta o posicionador para o início. */
20
java.io.InputStream void mark(int)
Marca a posição atual fazendo com que cada chamada ao método reset() faça o posicionador saltar para ali.
Ao chamar o método mark() devemos especificar a quantidade de bytes que, após lidos, realiza a remarcação automática do posicionador.
Este método não funciona para streams do tipo FileInputStream.
21
java.io.InputStream boolean markSupported()
Usado para verificar se o stream possui a funcionalidade do método mark() definido no slide anterior.
22
java.io.FileInputStream Uma implementação de InputStream que lê os dados
binários a partir de um arquivo de qualquer formato.
Ao instanciar um FileInputStream devemos especificar o caminho absoluto ou relativo do arquivo desejado.
InputStream input1 = new FileInputStream(“C:\\temp\\foto.jpg”);InputStream input2 = new FileInputStream(“docs\\plan1.xls”);. . .. . .input1.close();input2.close();
23
java.io.FileInputStream Uma outra forma de instanciar um FileInputStream é
utilizando alguma instância da classe java.io.File que já tenha sido previamente instanciada:
File file = new File(“C:\\temp\\foto.jpg”);InputStream input = new FileInputStream(file);. . .. . .input.close();
24
java.io.ByteArrayInputStream Uma implementação de InputStream que lê os dados
binários a partir de array de bytes.
Útil como argumento de passagem de parâmetros do tipo imagem, som ou outros dados binários para bibliotecas diversas, como:
Armazenamento em bancos de dados; Aplicações de edições de imagens, sons ou outros formatos; Geração dinâmica de relatórios.
byte[] dados = .....; /* Dados binários. */InputStream input = new ByteArrayInputStream(dados);
25
java.io.OutputStream Um OutputStream (também chamado de
stream de saída) representa uma entidade ou dispositivo para onde podemos empurrar informações byte a byte.
26
¦ ÿ À °Ý w
java.io.OutputStream void write(int)
Converte o valor especificado para byte e adiciona-o ao final do stream.
Em outras palavras, este método “empurra” um byte para o stream de saída.
OutputStream os = new FileOutputStream(“C:\\novo.tmp”);os.write(74);os.write(97);os.write(118);os.write(97);. . .
27
Alguma implementação de OutputStream
java.io.OutputStream void write(byte[])
Adiciona um array de bytes ao final do stream.
byte[] conteudo = { 74, 97, 118, 97, 32, 101, 104, 32, 108, 101, 103, 97, 108, 33 };
OutputStream os = new FileOutputStream(“C:\\novo.tmp”);os.write(conteudo);
28
Alguma implementação de OutputStream
java.io.OutputStream void write(byte[], int, int)
Adiciona um trecho de array de bytes ao final do stream.
byte[] conteudo = { 74, 97, 118, 97, 32, 101, 104, 32, 108, 101, 103, 97, 108, 33 };
OutputStream os = new FileOutputStream(“C:\\novo.tmp”);os.write(conteudo, 8, 5);
29
Posição inicial Quantidade de bytes
java.io.OutputStream void flush()
Algumas implementações de OutputStream utilizam sistema de cache de dados durante a escrita.
O cacheamento consiste em reter em memória parte das informações escritas, despachando-as para seu destino de tempos em tempos.
Em situações como esta, podemos forçar o envio de dados para seu stream de destino através do método flush().
O método flush() obriga o envio de dados em cache para seu destino.
30
java.io.OutputStream void close()
Encerra o stream de saída liberando o recurso (arquivo ou outra origem de dados) tornando-o disponível para utilização por outros programas do sistema operacional.
Este método obriga o stream a realizar o flush de todos os dados que porventura ainda estejam em cache.
OutputStream os = new FileOutputStream(“C:\\novo.tmp”);os.write(...);os.write(...);os.write(...);os.close();
31
java.io.FileOutputStream Uma implementação de OutputStream que escreve dados
binários em um arquivo sem utilização de cache.
Ao instanciar um FileOutputStream devemos especificar o caminho absoluto ou relativo do arquivo desejado.
Se o arquivo informado já existir, todo o seu conteúdo será sobreposto pelo que está sendo gravado. Se o arquivo ainda não existir, ele tentará ser criado.
OutputStream os = new FileOutputStream(“C:\\temp\\file.tmp”);. . .os.close();
32
java.io.FileOutputStream Também podemos utilizar algum File previamente
instanciado para definir o arquivo que será aberto;
File file = new File(“C:\\temp\\file.tmp”);OutputStream os = new FileOutputStream(file);. . .. . .os.close();
33
java.io.ByteArrayOutputStream Classe utilitária usada na manipulação de streams e
conversão para arrays de bytes.
Funciona como um stream de saída que retem todos os dados escritos em memória.
Ao final de toda a escrita, podemos converter o stream em um array.
ByteArrayOutputStream os = new ByteArrayOutputStream();os.write(...);os.write(...);. . .byte[] conteudo = os.toByteArray();
34
Arquivos de acesso randômico Através da classe java.util.RandomAccessFile
podemos ler e manipular informações em arquivos em formato DAT.
Um arquivo DAT é um arquivo binário utilizado tipicamente para guardar informações de tamanho fixo.
35
� � ...
nome idade salario
funcionario
...nome idade salario
funcionario
nome idade salario
funcionario
java.io.RandomAccessFile Ao instanciar um RandomAccessFile, devemos
informar o nome do arquivo e a forma de abrí-lo:
RandomAccessFile dataFile;dataFile = new RandomAccessFile(“C:\\agenda.dat”, “rw”);
Formas de abrir o arquivo:r – Abre o arquivo em modo somente leitura;rw – Abre o arquivo em modo leitura e escrita;rws – Abre o arquivo em modo leitura e escrita garantindo o
sincronismo entre dois ou mais processos que acessem simultaneamente o arquivo.
36
java.io.RandomAccessFileGravando dados: void writeInt(int)
Grava um número int ocupando 4 bytes
void writeLong(long)Grava um número long ocupando 8 bytes
void writeFloat(float)Grava um número float ocupando 4 bytes
void writeDouble(double)Grava um número double ocupando 8 bytes
void write(byte[])Grava um conjunto de bytes
void writeBoolean(boolean)Grava um boolean ocupando um byte
void writeByte(int)Converte o número para byte e grava
void writeShort(int)Converte o número para short e grava ocupando 2 bytes
void writeChar(int)Converte o número para char e grava ocupando 4 bytes
37
java.io.RandomAccessFileLendo dados: int readInt()
Lê os próximos 4 bytes retornando um int
long readLong()Lê os próximos 8 bytes retornando um long
float readFloat()Lê os próximos 4 bytes retornando um float
double readDouble()Lê os próximos 8 bytes retornando um double
int read(byte[], int, int)Lê um conjunto de bytes carregando-os em um array
boolean readBoolean()Lê o próximo byte retornando um boolean
byte readByte()Lê o próximo byte
short readShort()Lê os próximos 2 bytes retornando um short
char readChar()Lê os próximos 4 bytes retornando um char
38
Exercício Crie o pacote br.com.impacta.copy no mesmo projeto do
exercício anterior e copie para este pacote a classe FileCopyFrame fornecida pelo instrutor.
A classe FileCopyFrame é uma classe executável que exibe uma janela permitindo ao usuário digitar o nome de dois arquivos.
39
Exercício (Fim) Implemente a funcionalidade do botão Ok da janela
FileCopyFrame (método btnOkActionPerformed(), linha 170).
Ao clicar no botão Ok, a aplicação deverá copiar o arquivo especificado na primeira caixa de texto (txtOrigem) gerando uma cópia com o nome especificado na segunda caixa de texto (txtDestino).
Caso ocorra algum problema durante a cópia, uma mensagem de erro deverá ser exibida ao usuário com o comando JOptionPane.showMessageDialog().
40
Top Related