Atualizado: 21/09/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Buffering de Streams de Caracteres em Java com BufferedReader e BufferedWriter

Assim como os streams de bytes se beneficiam de buffers, os streams de caracteres (Reader e Writer) também possuem suas classes "decoradoras" para otimizar o desempenho: BufferedReader e BufferedWriter. Envolver FileReader e FileWriter com essas classes é a prática padrão para manipular arquivos de texto em Java, pois minimiza o número de acessos ao disco, que são operações lentas.

Escrita de Texto com Buffer usando BufferedWriter

A classe BufferedWriter envolve um Writer existente e armazena os caracteres a serem gravados em um buffer interno. A escrita no dispositivo físico só ocorre quando o buffer está cheio, quando o stream é fechado (close()), ou quando o método flush() é chamado. Isso reduz drasticamente a sobrecarga de I/O.

BufferedWriter possui os seguintes construtores:

BufferedWriter(Writer out)
BufferedWriter(Writer out, int sz)

O primeiro parâmetro é o Writer de destino. O segundo, opcional, permite especificar o tamanho do buffer.

O exemplo a seguir demonstra a escrita em um arquivo:

import java.io.*;

public class Program {

    public static void main(String[] args) {

        try (BufferedWriter bw = new BufferedWriter(new FileWriter("notes.txt"))) {
            String text = "Hello World!\nHey! Teachers! Leave the kids alone.";
            bw.write(text);
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }
}

Neste código, a chamada a bw.write(text) é extremamente rápida, pois apenas copia os caracteres para o buffer em memória. A estrutura try-with-resources garante que, ao final do bloco, bw.close() seja chamado. O método close(), por sua vez, chama flush() para assegurar que todos os dados do buffer sejam efetivamente gravados no arquivo.

Leitura de Texto com Buffer usando BufferedReader

Enquanto BufferedReader também melhora a performance da leitura, seu principal atrativo é um método que não existe na classe Reader base: readLine().

BufferedReader possui os seguintes construtores:

BufferedReader(Reader in)
BufferedReader(Reader in, int sz)

O método readLine() lê uma linha inteira de texto e a retorna como uma String, removendo os caracteres de terminação de linha (\n, \r, ou \r\n). Quando o final do stream é atingido, o método retorna null. Esta é a forma mais comum e idiomática de processar arquivos de texto em Java.

import java.io.*;

public class Program {

    public static void main(String[] args) {

        try (BufferedReader br = new BufferedReader(new FileReader("notes.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }
}

Exemplo Prático: Lendo do Console e Escrevendo em um Arquivo

As classes decoradoras podem ser encadeadas para construir funcionalidades complexas de forma elegante. O exemplo a seguir lê a entrada do usuário no console e a salva em um arquivo, linha por linha, até que o usuário digite "ESC".

import java.io.*;

public class Program {

    public static void main(String[] args) {

        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
             BufferedWriter bw = new BufferedWriter(new FileWriter("user_input.txt"))) {

            String text;
            while (!(text = br.readLine()).equalsIgnoreCase("ESC")) {
                bw.write(text);
                bw.newLine(); // Método conveniente para adicionar quebra de linha do sistema
                bw.flush();   // Garante que cada linha seja escrita imediatamente
            }
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }
}

Vamos analisar a cadeia de leitura do console:

  1. System.in: É um InputStream, ou seja, um fluxo de bytes brutos vindo do teclado.
  2. new InputStreamReader(System.in): É a "ponte" que envolve o InputStream e decodifica seus bytes em caracteres, usando a codificação padrão do sistema.
  3. new BufferedReader(...): Envolve o InputStreamReader para adicionar o buffering e, mais importante, o método readLine().

Dentro do laço, bw.flush() é chamado após cada escrita. Em um programa interativo, isso é crucial para garantir que o texto seja gravado no arquivo assim que o usuário pressiona Enter, em vez de esperar o buffer encher ou o programa terminar.


Resumo

  • BufferedWriter e BufferedReader são classes Decorator que adicionam buffering a Writer e Reader para otimizar a performance de I/O.
  • BufferedWriter armazena caracteres em um buffer e os escreve em grandes blocos. Ele também oferece o método newLine() para portabilidade.
  • A principal vantagem do BufferedReader é o método readLine(), que simplifica a leitura de arquivos de texto linha por linha.
  • A leitura de texto do console (System.in) é feita com a cadeia BufferedReader(new InputStreamReader(System.in)).
  • Em aplicações interativas, o uso de flush() pode ser necessário para garantir que os dados sejam gravados em tempo real.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com