1. Introdução
Imagine que você recebeu do contador um arquivo com um relatório salvo em "Windows-1251" (uma codificação antiga para o alfabeto cirílico). Seu aplicativo Java espera todos os dados de entrada em "UTF-8"; caso contrário, ele começa a “reclamar” e exibir caracteres estranhos no lugar das letras. Ou, por exemplo, você está se integrando a um sistema que aceita apenas "ISO-8859-1". O que fazer? Claro — recodificar o arquivo!
Recodificação — é o processo em que você lê texto de um arquivo em uma codificação e o salva em outra codificação. É como reescrever uma carta de um idioma para outro para garantir que o destinatário entenda perfeitamente a sua mensagem.
Como a recodificação funciona em Java: visão geral
Em Java, as strings (String) dentro do programa são sempre armazenadas em Unicode (UTF‑16). Isso significa que, ao ler o texto de um arquivo, ele já fica “universal” e pode ser gravado em qualquer codificação suportada. Portanto, recodificar é simples:
- Ler o arquivo como texto/linhas, informando a codificação de origem correta.
- Gravar essas linhas em um novo arquivo, especificando explicitamente a codificação de destino necessária.
Esquema:
[Arquivo na codificação A] --(leitura com Charset A)--> [String na memória] --(gravação com Charset B)--> [Arquivo na codificação B]
2. Passo a passo da recodificação
Etapa 1. Definir a codificação de origem e a de destino
A codificação de origem é aquela em que o arquivo original foi salvo (por exemplo, "Windows-1251"). A codificação de destino é aquela em que você deseja obter o resultado (por exemplo, "UTF-8").
Etapa 2. Abrir um stream para leitura com a codificação necessária
Use Files.newBufferedReader(Path, Charset) ou o clássico InputStreamReader.
Etapa 3. Abrir um stream para escrita com a codificação necessária
Use Files.newBufferedWriter(Path, Charset) ou o clássico OutputStreamWriter.
Etapa 4. Ler as linhas e escrevê-las em um novo arquivo
Leia linha a linha (ou o arquivo inteiro — se ele for pequeno) e grave cada linha no novo arquivo.
Etapa 5. Fechar os streams (de preferência com try-with-resources)
Assim garantimos a liberação correta dos recursos. Aplique a construção try-with-resources.
3. Exemplo de código: recodificação Windows-1251 → UTF-8
Vamos implementar um programa simples que recodifica um arquivo de Windows‑1251 para UTF‑8. Esse exemplo é comum na vida real, especialmente se você trabalha com dados em russo.
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
public class FileReencoder {
public static void main(String[] args) throws IOException {
// Caminhos dos arquivos
Path inputPath = Paths.get("input-1251.txt");
Path outputPath = Paths.get("output-utf8.txt");
// Abrimos o reader com a codificação de origem Windows-1251
try (
BufferedReader reader = Files.newBufferedReader(inputPath, Charset.forName("Windows-1251"));
BufferedWriter writer = Files.newBufferedWriter(outputPath, StandardCharsets.UTF_8)
) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine(); // não se esqueça da quebra de linha!
}
}
System.out.println("Arquivo recodificado com sucesso de Windows-1251 para UTF-8!");
}
}
Aqui especificamos explicitamente a codificação para leitura (Charset.forName("Windows-1251")) e para escrita (StandardCharsets.UTF_8). Em seguida, usamos try-with-resources para que os streams sejam fechados automaticamente mesmo em caso de erro. writer.newLine() — quebra de linha, para preservar a estrutura do arquivo.
4. Nuances importantes e dicas
Como descobrir a codificação de origem do arquivo?
- Um arquivo em si não contém um “rótulo” indicando a codificação (exceção — BOM, mas ele nem sempre está presente).
- Se o arquivo foi criado por você — use a mesma codificação utilizada na gravação.
- Se o arquivo veio “de algum lugar” — tente abri-lo em um editor que mostre a codificação (por exemplo, Notepad++, Visual Studio Code).
- No Linux, você pode usar o comando file -i nome_do_arquivo, mas ele nem sempre detecta a codificação corretamente.
O que acontece se você informar a codificação de origem errada?
Você obterá caracteres ilegíveis (mojibake) ou perda de caracteres. Por exemplo, se ler um arquivo salvo em Windows‑1251 como UTF‑8, o alfabeto cirílico se transformará em "Привет".
Tratamento de exceções
Ao trabalhar com arquivos, erros são sempre possíveis: arquivo não encontrado, falta de permissões, codificação inválida. Use tratamento de exceções (try-catch) ou propague-as (throws) para que o aplicativo não caia “sem explicação”.
Trabalhando com arquivos grandes
Se o arquivo for enorme (gigabytes!), use leitura e escrita linha a linha, como nos exemplos fornecidos. Não leia o arquivo inteiro na memória de uma vez — caso contrário, você terá um OutOfMemoryError.
Recodificação “on the fly” (streaming)
Se o arquivo for muito grande, você pode nem criar um arquivo intermediário, lendo e escrevendo “em tempo real” — por exemplo, ao processar dados de rede em fluxo.
5. Erros comuns na recodificação de arquivos
Erro nº 1: Codificação de origem incorreta. Se você errar a codificação de origem, o resultado será ruim: “Privet” se transformará em "Привет". Sempre descubra em que codificação o arquivo foi criado.
Erro nº 2: Uso implícito da codificação do sistema. Se você não informar a codificação explicitamente, o Java usa a padrão do sistema (System.getProperty("file.encoding")). Isso pode levar a resultados diferentes em computadores distintos (por exemplo, no Windows — cp1251; no Linux — UTF‑8).
Erro nº 3: Ler e escrever o arquivo inteiro na memória. Para arquivos grandes, essa abordagem causará estouro de memória. Use leitura e escrita linha a linha.
Erro nº 4: Exceções não tratadas. Os arquivos podem não existir, estar em uso por outros processos ou conter caracteres corrompidos. Sempre trate as exceções ou use try-with-resources.
Erro nº 5: Recodificação de arquivos binários. Não tente recodificar imagens, PDFs, arquivos compactados e outros arquivos binários! Isso irá corrompê-los. A recodificação só faz sentido para arquivos de texto.
GO TO FULL VERSION