Streams Java Sumário • Streams – Emprego – Tipos – Funcionalidades – Data Sink Streams – Processing Streams – Cadeias de Streams – Classes de Streams 2 Stream • Um programa lê / grava informações de / para um canal • Em Java, um canal de onde um programa pode ler ou gravar informações é chamado de Stream 3 Streams • Cada canal capaz de gravar em um destino de dados tem um conjunto de métodos de escrita • Cada canal capaz de ler a partir de uma fonte de dados tem um conjunto de métodos leitura • Quando o stream é criado só temos de invocar esses métodos 4 Input e Output Streams Input Stream Output Stream 5 Emprego de Streams • Na leitura: • construir e abrir um stream • enquanto há informações – ler as informações • fechar stream • Na gravação: • construir e abrir um stream • enquanto há informações para gravar – gravar informações • fechar stream 6 Tipos de Streams • Existem dois tipos de streams: –Streams de Bytes (classes *Stream) –Streams de Caracteres (classes *Reader ou *Writer) 7 Cópia de bytes 8 Cópia de bytes import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyBytes { public static void main(String[] args) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("xanadu.txt"); out = new FileOutputStream("outagain.txt"); int c; while ((c = in.read()) != -1) { out.write(c); } } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } 9 } } Cópia de caracteres import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class CopyCharacters { public static void main(String[] args) throws IOException { FileReader inputStream = null; FileWriter outputStream = null; try { inputStream = new FileReader("xanadu.txt"); outputStream = new FileWriter("characteroutput.txt"); int c; while ((c = inputStream.read()) != -1) { outputStream.write(c); } } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } 10 } } Streams • Funcionalmente: – Data Sink (Sumidouro) Streams conectados diretamente com a origem ou destino – Processing Streams - ligados a outros streams para proporcionar uma maior transparência de processamento (filtragem, compressão, etc.) 11 Data Sink Streams • Classes: – – – – FileReader: lê caracteres de um arquivo. FileWriter: grava caracteres em um arquivo. FileInputStream: lê bytes de um arquivo. FileOutputStream: grava bytes em um arquivo. • Data Sink Streams têm apenas métodos simples de leitura / gravação – Ao criar streams Data Sink temos de especificar a fonte • Para arquivos: o nome do arquivo • Para a rede: o socket • A partir de memória: a localização 12 Processing Streams • Processing Streams – Quando se cria um processing stream, temos de especificar a qual stream estará ele ligado • Alguns processing streams: – DataInputStream, DataOutputStream, BufferedWriter, BufferedReader, etc .. • Como fazer: – Ligar a um Datastream um FileStream para gravar / ler outros tipos de dados que não sejam bytes – Ligar a um BufferStream a um NetworkStream para “bufferizar” o acesso à rede 13 Cópia de linhas (com bufferização) import import import import import java.io.FileReader; java.io.FileWriter; java.io.BufferedReader; java.io.PrintWriter; java.io.IOException; public class CopyLines { public static void main(String[] args) throws IOException { BufferedReader inputStream = null; PrintWriter outputStream = null; try { inputStream = new BufferedReader(new FileReader("xanadu.txt")); outputStream = new PrintWriter(new FileWriter("characteroutput.txt")); String l; while ((l = inputStream.readLine()) != null) { outputStream.println(l); } } finally { if (inputStream != null) { inputStream.close(); } if (outputStream != null) { outputStream.close(); } } 14 } } Cadeias de Streams – Quando tudo estiver configurado e se desejar gravar um número real em um Data Stream (invocar qualquer método de gravar): • O programa pede ao data stream para gravar algo • O data stream obtém um conjunto de bytes e os grava no buffer stream • O buffer stream retém os bytes até que decida a gravá-los, de uma só vez, no file stream • O file stream efetivamente grava os bytes no arquivo destino sempre que os receber do buffer stream 15 Classes de Streams • Para cada tipo existe um InputStream (byte) ou Reader (char) e um OutputStream (byte) ou Reader (char) • As classes Stream podem ter sub classes – Pode-se criar seus próprios streams para serem incluído em uma cadeia • Para isto é preciso: – Criar o construtor da classe aceitando um Stream – Adaptar-se aos métodos de leitura / gravação e implementar as funcionalidades desejadas nesses métodos 16 Criação de processing streams • As classes base partir do qual derivam os novos processing streams são: – FilterOutputStream – FilterInputStream – FilterReader – FilterWriter 17 Classes para acesso a arquivos • • A classe InputStreamReader le bytes e os decodifica em caracteres Cada invocação do método read() de InputStreamReader's le um ou mais bytes da entrada • Para maior eficiência é conveniente “encapar” a classe InputStreamReader por uma classe BufferedReader. BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); • • 18 A classe RamdomAccessFile permite leitura e gravação de modo aleatório em arquivos de acesso direto Um ponteiro, posicionado pelo método seek(), indica o ponto de leitura Declaração de classe para acesso direto File file = new File("RandomAccessFileExample.out"); RandomAccessFile raf = new RandomAccessFile(file, "rw"); // Ler primeiro caractere do arquivo byte ch = raf.readByte(); System.out.println(“Ler primeiro caractere: " + (char)ch); // Incluir registro no final do arquivo raf.write(0x0A); raf.writeBytes(“Exemplo terminado"); 19 Exemplos de acessos a arquivos Exemplo 1 (acesso direto) FileInputStream stream = new FileInputStream("../EDIIA32.txt"); InputStreamReader streamReader = new InputStreamReader(stream); BufferedReader reader = new BufferedReader(streamReader); RandomAccessFile raf = new RandomAccessFile (new File("../AcessoDireto.dsk"), "rw"); arq.read(stringData); arq.writeInt(mpr_periodo); Exemplo 2 (acesso seqüencial) private static InputStreamReader is = new InputStreamReader( System.in ); private static BufferedReader br = new BufferedReader( is ); BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream ( new File(".\\dados\\ARQ9502.DAT")))); while (in.ready()) { linha = in.readLine(); 20