byte[] UTF-8 para string em C#: qual método é mais rápido e melhor?

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

Por que a questão "UTF-8 byte[] para string" não perde relevância?



Imagine: você recebeu um array de bytes de uma requisição de rede, leu um arquivo binário ou desserializou dados de uma API. Dentro dele — texto comum em português, inglês ou emojis. Mas o C# vê apenas byte[]. Sua tarefa é transformar esses zeros e uns em uma string compreensível string.



Parece simples, não? Uma chamada de método e pronto. Mas no Stack Overflow a pergunta "How to convert UTF-8 byte[] to string" acumula milhares de visualizações e dezenas de respostas. Por quê? Porque o diabo está nos detalhes: codificação, desempenho, segurança e exceções inesperadas.



Neste artigo, não vamos apenas fornecer o código pronto. Vamos comparar abordagens, medir a velocidade, discutir as armadilhas e escolher a melhor ferramenta para cada tarefa. Se você programa em C# e trabalha com rede, arquivos ou serialização — este material é para você.



O problema: byte[] não é uma string



Em C#, a string string é armazenada na codificação UTF-16. Já os bytes que você recebeu provavelmente estão codificados em UTF-8 (padrão da internet, JSON, a maioria dos protocolos de texto). A conversão direta de tipos é impossível — o compilador emitirá um erro.



É necessário um decodificador que converta a sequência de bytes UTF-8 em caracteres UTF-16. E é aqui que a coisa fica interessante: o desenvolvedor tem pelo menos três caminhos fundamentalmente diferentes.



Método 1: O clássico — Encoding.UTF8.GetString



A maneira mais óbvia e recomendada pela Microsoft é usar a classe estática System.Text.Encoding:



byte[] utf8Bytes = { 72, 101, 108, 108, 111, 32, 208, 191, 209, 128, 208, 176, 208, 178, 208, 176 }; // "Hello права"string result = Encoding.UTF8.GetString(utf8Bytes);Console.WriteLine(result); // Saída: Hello права


Vantagens:

  • Simplicidade — uma linha de código.
  • Suporte a todas as codificações, incluindo UTF-8, UTF-16, ASCII, Latin-1.
  • Tratamento embutido de BOM (Byte Order Mark) — se houver um marcador UTF-8 no início do array, ele será ignorado.
  • Segurança — sem blocos unsafe.


Desvantagens:

  • Cada chamada cria uma nova string e um buffer interno.
  • Se os bytes estiverem corrompidos ou contiverem uma sequência UTF-8 inválida, o método por padrão lançará uma DecoderFallbackException (se o fallback não for configurado).
  • Não é ideal para arrays muito grandes (centenas de megabytes) — cópia dupla de dados.


Quando usar?

Em 95% dos casos. É o padrão da indústria. Se você não está escrevendo um parser de alta carga ou trabalhando com gigabytes de logs — use Encoding.UTF8.GetString.



Método 2: Rápido e perigoso — unsafe com ponteiros



Para quem busca velocidade e não tem medo de unsafe. A ideia: sabemos que UTF-8 e UTF-16 são codificações diferentes, mas se o array contiver apenas caracteres ASCII (códigos até 127), cada byte pode ser "esticado" em um caractere de 2 bytes sem decodificação.



unsafe string UnsafeAsciiBytesToString(byte[] bytes){    fixed (byte* pBytes = bytes)    {        return new string((sbyte*)pBytes, 0, bytes.Length);    }}


Este código funciona apenas para ASCII! Para texto em português (caracteres > 127), o resultado será lixo. Mas para inglês puro, ele é 2 a 3 vezes mais rápido que Encoding.UTF8.GetString.



Vantagens:

  • Overhead mínimo — sem cópia, sem decodificação.
  • Ideal para analisar cabeçalhos HTTP, chaves JSON (se forem ASCII).


Desvantagens:

  • Perigoso para caracteres multibyte — corrompe dados.
  • Requer permissão unsafe no projeto (nem sempre permitido).
  • Não processa

Blogs

Book Recommendations