CodeGym /Cursos /JAVA 25 SELF /O que é codificação de caracteres e para que serve

O que é codificação de caracteres e para que serve

JAVA 25 SELF
Nível 37 , Lição 0
Disponível

1. Conceito de codificação (encoding)

Vamos começar com a pergunta principal: o que é codificação?

Imagine que você chegou a uma conferência internacional. Cada um fala seu idioma, mas todos querem se entender. Para isso, é preciso um tradutor que saiba que a palavra "hello" em inglês é "privet" em russo e "hola" em espanhol. No mundo dos computadores, a codificação é esse tradutor.

Codificação é uma forma de representar caracteres como bytes

O computador é uma máquina simples: ele entende apenas zeros e uns, isto é, bits e bytes. Já as pessoas querem ver letras, números, emojis e até — ó, horror! — ideogramas chineses. Para que o computador possa “gravar” um caractere, é preciso combinar a quais bytes cada caractere corresponderá.

Codificação (encoding) é o conjunto de regras segundo o qual os caracteres (letras, números, pontuação, emojis etc.) são transformados em bytes para armazenamento e transmissão e, no caminho inverso, bytes são transformados em caracteres para exibição.

Exemplo: a letra 'A' (cirílico) em diferentes codificações

  • Na codificação UTF-8, a letra 'A' (cirílico) é codificada em dois bytes: 0xD0 0x90.
  • Na codificação Windows-1251, a mesma letra é um byte: 0xC0.
  • Já a letra latina 'A' em quase todas as codificações populares é 0x41.

Se você ler um arquivo na codificação errada, os caracteres viram “caracteres estranhos” (símbolos incompreensíveis ou pontos de interrogação).

2. Por que precisamos de codificações

Por que não podemos simplesmente armazenar as letras como são?

Porque o computador entende apenas números (zeros e uns). Qual número corresponde a qual letra — essa é a essência da codificação.

Exemplo: “Privet” no disco

Quando você escreve no arquivo a palavra "Privet", para o computador isso é apenas uma sequência de bytes. Como interpretar esses bytes depende da codificação.

  • Se o arquivo estiver em UTF-8, cada letra cirílica ocupa dois bytes, e assim por diante.
  • Se estiver em Windows-1251, cada letra é um byte, mas com valores de byte diferentes.

Onde as codificações são necessárias?

  • Ao gravar texto em arquivo: para que os bytes possam ser lidos corretamente depois.
  • Ao ler texto de arquivo: para que os bytes virem letras novamente.
  • Ao enviar texto pela rede (por exemplo, HTTP, e-mail).
  • Ao trabalhar com bancos de dados: lá também é preciso saber em qual codificação o texto é armazenado.

Se você não informar a codificação...

É como abrir um texto em um idioma desconhecido e tentar lê-lo. As chances aumentam se você souber qual é o idioma. Se não souber — no melhor cenário você não entende nada; no pior — vira uma salada de caracteres.

3. Problemas sem a codificação correta

“Caracteres estranhos” e perda de dados

A reclamação mais comum de programadores iniciantes (e não só): “Por que em vez de "Privet" eu vejo "Привет" ou só um monte de interrogações?”

Isso acontece quando o arquivo foi gravado em uma codificação e é lido em outra. Por exemplo, o arquivo foi criado em um Windows antigo com Windows-1251, e você o abre no Linux, cujo padrão é UTF-8. Ou vice-versa.

Exemplo

  • Arquivo gravado em Windows-1251: o byte para a letra cirílica “Pe” (U+041F) é 0xCF.
  • Aberto em UTF-8: o programa espera que caracteres cirílicos usem dois bytes, mas recebe apenas um. Tudo quebra.

Perda de dados

Se, ao gravar, o caractere não for suportado pela codificação escolhida (por exemplo, tentar salvar um emoji em ASCII), ele desaparecerá ou será substituído por um ponto de interrogação. Tudo o que não “cabe” na codificação se perde.

Problemas ao trocar arquivos

Arquivos gravados em uma codificação podem ser exibidos incorretamente em outros computadores, se lá a codificação padrão for diferente. Isso acontece com frequência ao trocar arquivos entre Windows e Linux ou ao abrir arquivos antigos.

4. Codificação no Java: representação interna e externa

Dentro da JVM: sempre Unicode (UTF-16)

No Java, as strings (String) dentro do programa são sempre armazenadas em Unicode (mais precisamente, em UTF-16). Isso significa que você pode atribuir às variáveis strings em qualquer idioma do mundo, e o Java vai lidar com tudo.

String hello = "Olá, mundo! 😀";

Na memória da JVM, esse texto é armazenado como uma sequência de valores de 16 bits (char), em que cada caractere corresponde a um código na tabela Unicode.

Fato interessante
Em Java, um char tem 16 bits (2 bytes). Mas alguns caracteres (por exemplo, ideogramas raros ou emojis) exigem dois char — são os “pares substitutos”.

Entrada/saída: a codificação importa!

Quando você ou grava strings no “mundo externo” (arquivos, rede), o Java precisa converter a representação interna (UTF-16) em uma sequência de bytes. É aí que entra a codificação.

  • Se você não informar explicitamente a codificação, o Java usará a do sistema por padrão (em um Windows em russo pode ser Windows-1251, no Linux — UTF-8).
  • Isso é perigoso: em outro computador o resultado pode ser diferente.

Exemplo: leitura e gravação de arquivo sem informar a codificação

// Má prática! A codificação não foi informada.
FileReader reader = new FileReader("data.txt");
FileWriter writer = new FileWriter("data.txt");

Nesse caso, o Java usa a codificação do sistema. Se o arquivo foi gravado em outro sistema — você terá “caracteres estranhos”.

Boa prática: sempre informar a codificação

// Bom! A codificação foi informada explicitamente.
BufferedReader reader = new BufferedReader(
    new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.UTF_8));
BufferedWriter writer = new BufferedWriter(
    new OutputStreamWriter(new FileOutputStream("data.txt"), StandardCharsets.UTF_8));

5. Ilustração rápida: o que acontece ao trabalhar com codificações

Esquema: o caminho da string do arquivo ao programa e de volta

[Arquivo no disco (bytes, codificação X)]
        |
        V
[Java lê os bytes e, com a codificação X, converte para String (UTF-16)]
        |
        V
[Você trabalha com a string no programa]
        |
        V
[Java grava a String em bytes usando a codificação Y]
        |
        V
[Arquivo no disco (bytes, codificação Y)]

Se X e Y coincidirem — tudo certo. Se forem diferentes — podem ocorrer problemas.

6. Breve história das codificações (para curiosos)

ASCII

ASCII é uma das codificações mais antigas: um byte por caractere, apenas o alfabeto inglês, dígitos e sinais básicos. Outros alfabetos — ficam de fora.

Windows-1251, ISO-8859-1 e outros “veteranos”

São codificações de um byte para diferentes conjuntos de letras: cirílico, latino, grego etc. Cada um escolhia a sua e começou a confusão.

Unicode e a família UTF

  • Unicode — tabela global para os caracteres do mundo.
  • UTF-8, UTF-16, UTF-32 — diferentes formas de representar caracteres Unicode em bytes.
  • UTF-8 tornou-se o padrão para Web, arquivos e integração entre sistemas.

7. Prática: como a codificação afeta o trabalho com arquivos

Vamos ver um pequeno exemplo de gravação e leitura de strings com codificações diferentes.

Exemplo: gravação e leitura em codificações diferentes

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class EncodingDemo {
    public static void main(String[] args) throws IOException {
        String text = "Olá, mundo! 😀";

        // Vamos gravar o arquivo em UTF-8
        try (Writer writer = new OutputStreamWriter(
                new FileOutputStream("utf8.txt"), StandardCharsets.UTF_8)) {
            writer.write(text);
        }

        // Agora vamos tentar lê-lo na codificação errada
        try (Reader reader = new InputStreamReader(
                new FileInputStream("utf8.txt"), Charset.forName("Windows-1251"))) {
            int c;
            while ((c = reader.read()) != -1) {
                System.out.print((char) c);
            }
        }
        // Na tela sairá texto ilegível!
    }
}

Conclusão: Se as codificações não coincidirem — o texto será corrompido.

8. Codificação e integração com outros sistemas

Em projetos reais, os arquivos frequentemente são trocados entre programas diferentes, escritos em linguagens diferentes e executando em sistemas operacionais distintos. Cada um pode esperar sua própria codificação. Se não houver um acordo prévio — você terá “caracteres estranhos” e bugs difíceis de rastrear. Caso típico: o banco de dados armazena texto em UTF-8, mas o programa lê o arquivo de origem como Windows-1251 e carrega no BD — os caracteres saem corrompidos.

9. Erros típicos ao trabalhar com codificações

Erro nº 1: Codificação não informada ao ler/gravar arquivo.
Como resultado, “funciona no meu computador”, mas no do colega — “caracteres estranhos”.

Erro nº 2: Uso de construtores obsoletos (FileReader, FileWriter).
Eles sempre utilizam a codificação do sistema — uma armadilha para iniciantes.

Erro nº 3: Codificação incorreta do arquivo de origem.
Se o arquivo foi gravado em uma codificação e é lido em outra, parte dos caracteres será corrompida ou substituída por interrogações.

Erro nº 4: Perda de caracteres ao migrar entre codificações.
Se a codificação de destino não suportar todos os caracteres (por exemplo, ASCII em vez de UTF-8), parte do texto simplesmente desaparecerá.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION