Como ler um arquivo em uma string Java: análise por baixo dos panos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como ler um arquivo em uma string Java: análise de uma pergunta popular do Stack Overflow

\n\n

Se você já se perguntou "How do I create a Java string from the contents of a file?" — você não está sozinho. Esta pergunta acumulou milhares de visualizações no Stack Overflow, e não é à toa. Uma operação aparentemente simples — ler um arquivo de texto e colocar seu conteúdo em uma string — esconde várias armadilhas: desde vazamentos de memória até problemas de codificação.

\n\n

Neste artigo, não vamos apenas dar receitas prontas. Vamos analisar por baixo dos panos de cada método: como funciona o BufferedReader, por que o Files.readString() só apareceu no Java 11, e como o Scanner difere do InputStream. Vamos lá!

\n\n

Por que isso é mais complicado do que parece?

\n\n

À primeira vista, a tarefa é trivial: existe um arquivo, existe uma string. Mas Java é uma linguagem com tipagem forte e gerenciamento de memória. Para ler um arquivo, é necessário:

\n\n
    \n
  • Abrir um fluxo de dados (InputStream, Reader)
  • \n
  • Bufferizar a leitura (para não acessar o disco a cada byte)
  • \n
  • Reunir os bytes/caracteres em um buffer único
  • \n
  • Converter para string considerando a codificação
  • \n
  • Fechar os recursos (para evitar vazamento de descritores de arquivo)
  • \n
\n\n

Cada um desses passos é um ponto potencial de falha. Vamos analisar as abordagens mais populares.

\n\n

Método 1: Clássico — BufferedReader (Java 1.1+)

\n\n

O método mais antigo e testado. Usa BufferedReader para leitura linha por linha. Internamente, um buffer (padrão de 8 KB) acumula dados, reduzindo o número de chamadas de sistema read().

\n\n
public static String readFileBufferedReader(String filePath) throws IOException {\n    StringBuilder content = new StringBuilder();\n    try (BufferedReader reader = new BufferedReader(new FileReader(filePath, StandardCharsets.UTF_8))) {\n        String line;\n        while ((line = reader.readLine()) != null) {\n            content.append(line).append(System.lineSeparator());\n        }\n    }\n    return content.toString();\n}
\n\n

Como funciona por baixo dos panos?

\n

FileReader abre o arquivo e cria um FileInputStream. BufferedReader o envolve, adicionando um buffer. Ao chamar readLine(), um bloco de dados (por exemplo, 8 KB) é lido, e a linha é montada a partir do buffer. Se a linha for maior que o buffer, o buffer é relido. O try-with-resources garante o fechamento do fluxo mesmo em caso de exceção.

\n\n

Vantagens: Funciona em qualquer versão do Java, leitura linha por linha controlada.
\nDesvantagens: Adiciona um separador de linha extra no final, ineficiente para arquivos enormes (string na memória).

\n\n

Método 2: Scanner — prático, mas lento (Java 5+)

\n\n

Muitos gostam do Scanner pela simplicidade. Ele consegue dividir a entrada em tokens, mas para ler o arquivo inteiro é usado assim:

\n\n
public static String readFileScanner(String filePath) throws IOException {\n    try (Scanner scanner = new Scanner(new File(filePath), StandardCharsets.UTF_8.name())) {\n        scanner.useDelimiter("\\\\A"); // Início do arquivo como delimitador\n        return scanner.hasNext() ? scanner.next() : "";\n    }\n}
\n\n

Magia do \\\\A: É uma expressão regular que denota o início dos dados de entrada. Ao defini-la como delimitador, forçamos o Scanner a ler todo o conteúdo de uma só vez. Internamente, o Scanner usa Pattern para encontrar o delimitador, o que adiciona custos extras com expressões regulares.

\n\n

Vantagens: Código muito conciso.
\nDesvantagens: Mais lento que o BufferedReader devido ao uso de regex, não adequado para arquivos binários.

\n\n

Método 3: Files.readAllLines() — praticidade do Java 8 (NIO)

\n\n

A partir do Java 8, o pacote java.nio.file ofereceu uma maneira elegante

Blogs

Book Recommendations