Streams

  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Streams as PDF for free.

More details

  • Words: 1,605
  • Pages: 4
STREAMS (FLUXOS) EM JAVA – uma Introdução São objetos que permitem obter dados de qualquer fonte de entrada ("fluxo") ou enviar para qualquer fluxo de saída, de forma essencialmente idêntica. Essas fontes e destinos podem ser arquivos de disco, áreas da memória (buffers) , conexões de rede, e os tradicionais arquivos padrão de entrada (teclado) e saída (monitor de vídeo e impressora). A linguagem Java trabalha com um conjunto de mais de 50 classes de fluxos diferentes. Mas todas derivam (estendem) as classes abstratas básicas abaixo descritas. Há ainda interfaces usadas para designar fluxos, o que torna a linguagem muito flexível, mas ao mesmo tempo requer um estudo aprofundado, para tirar proveito dessa variedade. Classes abstratas básicas para leitura/escrita de bytes: InputStream e OutputStream. Classes abstratas básicas para leitura/ escrita de caracteres Unicode: Reader e Writer. Essas classes não são instanciáveis, mas fornecem o protocolo comum para todas as demais subclasses. Subclasses concretas são usadas para diversos meios de entrada e saída, e diversas formas de leitura e escrita de dados. InputStream (métodos de instância) Possui um método abstrato read() que é implementado nas subclasses, para ler 1 byte da entrada. Os demais métodos são concretos, os mais usados são apresentados abaixo. Procure verificar na API. public int available() throws IOException Retorna o número de bytes que podem ser lidos (ou pulados) desse InputStream sem bloqueio pela próxima chamada de um método para esse input stream. public void close() throws IOException Fecha o receptor da mensagem (ele não poderá mais ser usado para leitura) e libera os recursos do sistema operacional associados a ele. public void mark(int readlimit) Marca a posição corrente deste InputStream. public boolean markSupported() Testa se o receptor suporta os métodos mark e reset. public abstract int read() throws IOException Retorna o próximo byte da entrada, ou –1 se o fim do fluxo de entrada foi alcançado. Note que para obter o retorno como byte é preciso usar um cast pois o tipo de retorno é int. Esse método é abstrato, e precisa ser implementado nas classes concretas. public int read(byte[] b) throws IOException Lê do fluxo de entrada no máximo um número de bytes igual ao tamanho do buffer b (b.length). Retorna o número de bytes lidos ou –1 se não houver bytes disponíveis. Os bytes são lidos para b[0], b[1], etc. public int read(byte[] b, int inicio,int max) throws IOException Lê do fluxo receptor no máximo max bytes para o vetor de bytes b, iniciando na posição inicio. Ou seja, se houverem 0 < k <= max bytes disponíveis para leitura, eles serão lidos para as posições b[inicio], b[inicio+1],..., b[inicio+k-1]. O método retorna o número de bytes lidos, ou –1 caso não haja nenhum byte disponível para leitura (fim-de-arquivo). Esse método pode lançar uma exceção da classe IndexOutOfBoundsException se as expressões de índices ultrapassarem os limites do vetor. public void reset()throws IOException Reposiciona a stream para a posição no momento em que o método mark foi chamado pela última vez nesta input stream. public long skip(long n) throws IOException Ignora os n primeiros bytes de dados desta stream de entrada. Para maior eficiência, usa-se o método available() para saber quantos bytes estão disponíveis para leitura, e então lê-se todos para um buffer de tamanho suficiente com read (byte[]).

Por exemplo, se input for uma (sub-classe) de InputStream: int bytesDisponiveis = input.available(); if (bytesDisponiveis > 0) { byte[] buf = new byte[bytesDisponiveis]; input.read(buf); } Recomenda-se fechar o fluxo depois de usá-lo, para liberar os recursos alocados pelo sistema operacional. Para isso, enviar ao fluxo a mensagem close(): Ex: input.close();

OutputStream Essa é a classe abstrata raiz de todas as classes que fornecem o serviço de escrita de bytes em um fluxo de saída. public void close() throws IOException Fecha o fluxo de saída receptor da mensagem (ele não poderá mais ser usado nem reaberto) e libera os recursos do sistema operacional associados a ele. Se houver bytes ainda no buffer, eles serão descarregados na saída antes de fechar o fluxo. O método da classe OutputStream não faz nada. Ele é redefinido em cada uma das subclasses concretas. public void flush() throws IOException Descarrega os bytes que estejam no buffer do fluxo na saída associada. public void write(byte[] b) throws IOException Escreve todos os bytes do vetor b bytes no fluxo receptor da mensagem. Equivale a chamar o método write (b, 0, b.length) . public void write(byte[] b, int inicio,int n) throws IOException Escreve n bytes do vetor de bytes b, iniciando na posição inicio , no fluxo receptor da mensagem. Ou seja, serão escritos os bytes b[inicio], b[inicio+1],..., b[inicio+n-1] Esse método pode lançar uma exceção IndexOutOfBoundsException se as expressões de índices ultrapassarem os limites do vetor. public abstract void write(int b) throws IOException Escreve o byte menos significativo (posições 0 a 7) do argumento (que é um int) no fluxo receptor da mensagem. Os demais 24 bits do argumento são ignorados. Esse método é abstrato, e precisa ser implementado nas subclasses concretas. Recomenda-se fechar o fluxo de saída depois de usá-lo, para liberar os recursos alocados pelo sistema operacional e forçar a descarga de quaisquer bytes que tenham ficado retidos no buffer. Para isso, enviar ao fluxo a mensagem close(): Ex: output.close(); Os métodos acima podem lançar uma IOException se ocorrer algum erro na escrita dos dados, em particular se o fluxo de saída tiver sido fechado. Também podem lançar uma NullPointerException se a referência ao vetor b for nula.

Reader e Writer São as classes abstratas das quais descendem as diversas classes especializadas para ler e escrever fluxos de caracteres Unicode. Subclasses para ler/gravar arquivos: Para ler e gravar arquivos texto, usamos FileReader e FileWriter. Essas classes lêem um caractere a cada vez, o que é ineficiente. Normalmente vamos querer ler/escrever linhas inteiras. Linhas são seqüências de caracteres terminadas por uma marca de fim de linha, que é em geral o caractere newline ('\n'). Para ler uma linha de cada vez, usa-se o método readLine() da classe BufferedReader. Para criar um objeto dessa classe, passa-se para o seu construtor uma instância de alguma classe básica, como FileReader. O exemplo abaixo mostra como ler dados de um arquivo texto de nome "arquivo.txt" que está no mesmo diretório que o programa:

FileReader reader = new FileReader("arquivo.txt"); BufferedReader br = new BufferedReader(reader); String linha; while ((linha=br.readLine())!= null) { etc. } A cada execução de br.readLine() uma nova linha será retornada na forma de uma String. Quando não houver mais linhas, o método retorna null (e não uma String vazia, cuidado!). Gravando linhas em um arquivo texto Para gravar linhas em um arquivo texto, usamos um BufferedWriter, para evitar gravar caractere a caractere. Nesta classe, não há um correspondente método writeLine(). Em vez disso, há o método write(String linha, int deslocamento, int numChars); Esse método grava no arquivo uma linha contendo os numChars caracteres da String linha, a partir da posição deslocamento. Portanto, para gravar uma linha com a String toda, devemos escrever: write (linha, 0, linha.length()); A gravação não inclui a marca de fim de linha. Para colocá-la pode-se usar o método newLine(), ou colocar direto o caratere newline com write('\n'); IMPORTANTE: o método write() de BufferedWriter escreve para um buffer da memória, e só quando ele fica cheio é que os caracteres são transmitidos para o arquivo. É preciso forçar a gravação com flush(), caso contrário nada será realmente gravado. O método close() fecha o fluxo. Deveria forçar um flush, mas não o faz. No exemplo a seguir, todas as strings de um vetor de Strings serão gravadas, linha a linha, em um arquivo. String[] v = {"aaa", "bbbb", "ccccc"}; BufferedWriter bw = new BufferedWriter (new FileWriter("arquivo.txt")); for (int i=0; i< v.length(); i++){ write(v[i], 0, v[i].length()); bw.newLine();// grava uma marca de fim de linha } bw.flush(); //descarrega o conteudo do buffer da memoria no arquivo bw.close();

Um programa exemplo completo O programa abaixo, na primeira parte, lê um arquivo texto qualquer do disco, e imprime na console um máximo de 10 linhas (ou menos se não houver tantas linhas). Na segunda parte, um vetor de ints com valores aleatórios entre 0 e 999 é construído. O conteúdo desse vetor é gravado em um arquivo (binário, não texto) no disco. Depois o arquivo é lido de novo para um outro vetor de ints na memória: import java.io.*; import java.util.Random; public class TestaStreams{ public static void main (String[] args) throws IOException{ //Lendo e imprimindo no maximo 10 linhas de um arquivo-texto para a console: FileReader reader = new FileReader("c:\\testeStream.txt"); BufferedReader br = new BufferedReader(reader); String linha; int linhasLidas=0; while ((linha=br.readLine())!= null && linhasLidas<=10){ System.out.println(linha); linhasLidas++;

} //Gravando um vetor de ints e lendo mais tarde: int[] v = new int[100]; int i; // Cada posicao do vetor recebe um int aleatorio entre 0 e 999 Random gen = new Random(); for(i=0; i<100; i++) v[i] = gen.nextInt(1000); FileOutputStream fos = new FileOutputStream("vetInteiros.dat"); DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(fos)); for (int n:v) dos.writeInt(n);

//obs: usando foreach com vetor

dos.flush(); //necessario se usar BufferedOutputStream // Criando uma stream de leitura para dados, nao bufferizada nesse caso: DataInputStream dis =new DataInputStream(new FileInputStream("vetInteiros.dat")); // Criando uma area na memoria para receber os ints do arquivo. // O tamanho do vetor vai acomodar exatamente o no. de ints disponiveis no arquivo: int bytesDisponiveis = dis.available(); System.out.println("No. de bytes disponiveis para leitura = "+ bytesDisponiveis); int[] v2 = new int[bytesDisponiveis/4]; // lendo os inteiros um a um, do arquivo para a memoria (vetor v2): for(i=0; i

Related Documents

Streams
May 2020 14
Boats & Streams
June 2020 17
Oracle Streams
November 2019 11
Oracle Streams
May 2020 4
Streams 14
April 2020 4