Capítulo 10 Stream – Fluxo I/O Arquivos texto java.io.Reader java.io.FileReader java.io.BufferedReader java.io.Writer java.io.FileWriter java.io.BufferedWriter java.io.PrintWriter 2 Arquivos texto Um arquivo texto é um arquivo que contém informações legíveis e editáveis por quaisquer editores de texto, como o Notepad, Edit, VI e outros. Um arquivo texto pode possuir qualquer extensão, mas geralmente utilizamos a extensão TXT. Através do pacote java.io podemos utilizar classes do Java para leitura e gravação de texto em arquivos deste tipo. 3 Arquivos texto [Abstract] Reader read() : int read(char[]) : int read(char[], int, int) : int skip(long n) : long ready() : boolean close() : void FileReader BufferedReader readLine() : String FileWriter [Abstract] Writer write(String) : void write(char[]) : void flush() : void close() : void BufferedWriter newLine() : void PrintWriter print(String) : void println(String) : void printf(String, Object...) : PrintWriter 4 Arquivos texto java.io.Reader Classe abstrata que representa Classe abstrata que representa algum alguma fonte de dados em formato texto. destino de dados em formato texto. java.io.FileReader java.io.FileWriter Representa algum arquivo texto onde Representa algum arquivo texto de onde podemos ler dados caracter a caracter. java.io.Writer podemos escrever caracter a caracter. java.io.BufferedWriter Representa uma saída de texto onde java.io.BufferedReader podemos escrever linha a linha. Representa alguma fonte de texto de onde podemos ler linha a linha java.io.PrintWriter Representa uma saída de texto onde podemos escrever linha a linha, inclusive dados formatados. 5 java.io.Reader Um Reader (também chamado de leitor) representa um montante de informações em formato texto enfileirados de onde podemos capturar seus dados caracter a caracter. Algumas implementações desta classe podem também capturar dados linha a linha. Uma instância da classe Reader possui um posicionador apontando para algum de seus caracteres. A cada leitura realizada o posicionador captura o caracter e avança para o próximo, tornando-o disponível para nova leitura. J a v a é \n D i v e r t i d o 6 java.io.Reader int read() Realiza a leitura do caracter da vez retornando um número inteiro a ser convertido para char e avança para o próximo caracter. Caso o posicionador estiver apontando para depois do último caracter, este método retorna o valor -1. 7 java.io.Reader Reader reader = new FileReader(“C:\\carta.txt”); char[] dados = new char[4]; dados[0] = (char) reader.read(); Alguma implementação dados[1] = (char) reader.read(); de Reader dados[2] = (char) reader.read(); dados[3] = (char) reader.read(); reader.close(); String texto = new String(dados); System.out.println(texto); J a v a é \n D i v e r t i d o 8 java.io.Reader int read(char[]) Principal método da classe Reader. Realiza a leitura de diversos caracteres de uma só vez armazenando-os no array especificado. Após realizar a leitura este método retorna um número inteiro informando quantos caracteres foram realmente lidos. 9 java.io.Reader Reader reader = new FileReader(“C:\\carta.txt”); char[] dados = new char[4]; /* Realiza a leitura dos próximos 4 caracteres. */ int quant = reader.read(dados); reader.close(); String texto = new String(dados); System.out.println(texto); J a v a é \n D i v e r t i d o 10 java.io.Reader int read(char[], int, int) Realiza a leitura de diversos caracteres 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 caracteres foram realmente lidos. 11 java.io.Reader long skip(long) Avança o posiciondor de leitura sem capturar nenhuma informação do reader. Reader reader = new FileReader(“C:\\carta.txt”); char[] dados = new char[35]; reader.read(dados); /* Lê 35 caracteres. */ reader.skip(20); /* “Pula” 20 posições. */ reader.read(dados); /* Lê mais 35 caracteres. */ reader.close(); 12 java.io.Reader boolean ready() Verifica se na posição atual há algum caracter disponível para leitura. Retorna true quando há algum caracter ou false quando o posicionador estiver apontando para após o último caracter do arquivo. J a v a é \n D i v e r t i d o 13 java.io.Reader Reader reader = new FileReader(“C:\\plan1.xls”); while (reader.ready()) { System.out.print((char) reader.read()); } reader.close(); 14 java.io.Reader void close() Encerra a entrada de texto 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 reader. Reader reader = new FileReader(“C:\\carta.txt”); ... ... reader.close(); 15 java.io.FileReader Uma simples implementação de Reader que lê dados caracter a caracter a partir de um arquivo texto. Ao instanciar um FileReader devemos especificar o caminho absoluto ou relativo do arquivo desejado. Reader reader1 = new FileReader(“C:\\temp\\carta.txt”); Reader reader2 = new FileReader(“docs\\rascunho.txt”); ... ... reader1.close(); reader2.close(); 16 java.io.BufferedReader Outra implementação de Reader que pode ler dados linha a linha a partir de algum outro reader já instanciado. Seu método mais utilizado é o readLine() que retorna uma linha de texto inteira a partir do reader especificado. BufferedReader reader = new BufferedReader(new FileReader(“C:\\carta.txt”)); while (reader.ready()) { System.out.println(reader.readLine()); } reader.close(); 17 java.io.Writer Um Writer (também chamado de escritor) representa uma entidade ou dispositivo para onde podemos empurrar informações de texto. I m p a c t a 18 java.io.Writer void write(String) Método mais utilizado do writer que permite escrever um string ao final do texto Writer writer = new FileWriter(“C:\\carta.txt”); writer.write(“Java é divertido”); writer.close(); 19 java.io.Writer void write(int) Converte o valor especificado para char e escreve ao final do texto. Writer writer = new FileWriter(“C:\\carta.txt”); writer.write(74); // J writer.write(97); // a writer.write(118); // v Alguma implementação writer.write(97); // a de OutputStream writer.close(); ... 20 java.io.Writer void write(char[]) Adiciona um array de caracteres ao final do texto. char[] conteudo = { ‘J’, ‘a’, ‘v’, ‘a’, ‘ ’, ‘é’, ‘ ’, ‘d’, ‘i’, ‘v’, ‘e’, ‘r’, ‘t’, ‘i’, ‘d’, ‘o’ }; Writer writer = new FileWriter(“C:\\carta.txt”); writer.write(conteudo); writer.close(); Alguma implementação de OutputStream 21 java.io.Writer void write(char[], int, int) Adiciona um trecho de array de caracteres ao final do texto. char[] conteudo = {‘J’, ‘a’, ‘v’, ‘a’, ‘ ’, ‘é’, ‘ ’, ‘d’, ‘i’, ‘v’, ‘e’, ‘r’, ‘t’, ‘i’, ‘d’, ‘o’ }; Writer writer = new FileWriter(“C:\\carta.txt”); writer.write(conteudo, 7, 9); writer.close(); Posição inicial Quantidade de bytes 22 java.io.Writer void flush () Obriga o envio de dados em cache para seu destino. Writer writer = new FileWriter(“C:\\carta.txt”); writer.write(...); writer.write(...); writer.flush(); Esvazia o cache forçando os writer.write(...); dados em memória para saída writer.write(...); writer.flush(); writer.write(...); writer.close(); 23 java.io.Writer void close() Encerra a saída de texto liberando o recurso (arquivo ou outro meio de gravação) tornando-o disponível para utilização por outros programas do sistema operacional. Este método obriga o texto a realizar o flush de todos os dados que porventura ainda estejam em cache. Writer writer = new FileWriter(“C:\\carta.txt”); writer.write(...); writer.write(...); writer.write(...); writer.close(); 24 java.io.FileWriter Uma simples implementação de Writer que escreve texto em um arquivo. Ao instanciar um FileWriter devemos especificar o caminho absoluto ou relativo do arquivo desejado. No exemplo abaixo, se o arquivo informado já existir, todo o seu conteúdo será eliminado após a instanciação. Writer writer = new FileWriter(“C:\\carta.txt”); ... writer.close(); 25 java.io.FileWriter Ao instanciar um FileWriter podemos informar que seus dados serão “appendados” (escritos ao final do texto já existente). Isto evita que o arquivo seja limpo após a instanciação: Writer writer = new FileWriter(“C:\\carta.txt”, true); ... writer.close(); 26 java.io.BufferedWriter Outra implementação de Writer que possui o método adicional newLine() utilizado para escrever a “quebra de linha”. Um BufferedWriter deve ser instanciado a partir de algum outro Writer: BufferedWriter writer = new BufferedWriter(new FileWriter(“C:\\carta.txt”)); writer.write(“Linha 1”); writer.newLine(); writer.write(“Linha 2”); writer.close(); 27 java.io.PrintWriter Uma sofisticada implementação de Writer onde podemos escrever textos e números formatados. Seus principais métodos são: print() println() printf() PrintWriter writer = new PrintWriter( “C:\\carta.txt”); writer.print(“Prêmio ”); writer.println(“Acumulado”); writer.printf(“da megasena: %,.2f”, 42500000); writer.close(); 28 Exercício – Editor de Texto em Java A partir da classe TabajaraEditorFrame construída pelo Eclipse VE, implemente os comandos do itens “Novo”, “Abrir”, “Salvar” e “Sair” conforme especificado no próximo slide 29 Exercício (continuação) Comando “Novo” Limpa a caixa de texto 30 Exercício (continuação) Comando “Abrir” Solicita que o usuário escolha um arquivo através do comando jfcArquivo.showOpenDialog(); Se o comando acima retornar o valor da constante JFileChooser.APPROVE_OPTION, significa que o usuário selecionou corretamente um arquivo. Neste caso utilize o comando abaixo para capturar o arquivo selecionado: File arquivo = jfcArquivo.getSelectedFile(); Carregue a caixa de texto com todo o conteúdo do arquivo acima. 31 Exercício (continuação) Comando “Salvar” Solicita que o usuário escolha arquivo existente ou digite o nome de um novo arquivo através do comando jfcArquivo.showSaveDialog(); Se o comando acima retornar o valor da constante JFileChooser.APPROVE_OPTION, salve todo o conteúdo da caixa de texto no arquivo obtido pelo comando abaixo: File arquivo = jfcArquivo.getSelectedFile(); 32 Exercício (fim) Sair Fecha a janela com o método dispose() 33 Exercício (desafio 1) Sobrepor arquivo existente Altere o comando “Salvar” para que verifique se o arquivo selecionado já existe. Se sim, pergunte ao usuário se deseja sobrepor o arquivo selecionado. Se o objeto jfcArquivo já possui um arquivo selecionado, não é necessário exibir novamente a caixa de diálogo “Salvar”. Desta forma, o nome do arquivo só será perguntado na primeira vez. 34 Exercício (desafio 2) Confirmação de fechamento Ao fechar a janela verifique se o conteúdo da caixa de texto já foi salvo. Dica Crie um atributo booleano saved na classe que será utilizada pelos comandos para lembrar se o texto foi salvo ou não; Altere a propriedade defaultCloseOperation da janela para NOTHING_ON_CLOSE. Desta forma você terá controle sobre o clique no botão fechar; Implemente o evento windowClosing de sua janela para fazer a verificação antes de fechar a janela. 35