Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Na rotina de manipulação de dados, especialmente ao lidar com protocolos de comunicação ou armazenamento de mensagens serializadas, é comum precisar saber o tamanho de uma string quando ela for codificada em UTF-8. No entanto, gerar essa codificação completa apenas para medir seu comprimento pode ser ineficiente, principalmente com textos longos ou em sistemas com restrições de performance. Este artigo aborda uma abordagem prática para calcular de forma eficiente o tamanho em bytes de uma string UTF-8 no Java, sem precisar codificá-la de fato.
A questão central é: há uma maneira de determinar o tamanho que uma string ocupará em UTF-8 sem executar a operação de codificação completa? A resposta rápida é que a API padrão do Java não fornece um método direto para isso. O método getBytes("UTF-8") realiza a codificação e retorna um array de bytes, cujo comprimento indica o tamanho. Para strings grandes, esse processo pode ser custoso, além de gerar alocação de memória desnecessária.
Diante disso, a solução envolve entender a estrutura do UTF-8 e implementar uma função que percorre os caracteres da string, contando o número de bytes que cada um ocuparia na codificação, sem realizar a codificação.
A codificação UTF-8 representa caracteres Unicode usando uma quantidade variável de bytes:
Portanto, uma implementação eficiente precisa distinguir esses intervalos e tratar corretamente os pares de surrogates, que representam caracteres fora do BMP (Basic Multilingual Plane).
A seguir, apresento uma implementação baseada na especificação do UTF-8, que percorre cada caractere, verificando seu intervalo e acumulando o tamanho correspondente. Importante: a implementação não verifica se a string é bem formada. ela assume que os pares de surrogates estão corretos. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta.
public class Utf8LengthCalculator {
public static int getUtf8Length(CharSequence sequence) {
int length = 0. for (int i = 0. i < sequence.length(). i++) {
char ch = sequence.charAt(i). if (ch <= 0x7F) {
// ASCII: 1 byte
length += 1. } else if (ch <= 0x7FF) {
// U+0080 a U+07FF: 2 bytes
length += 2. } else if (Character.isHighSurrogate(ch)) {
// Surrogate pair: 4 bytes
length += 4. i++. // pular o low surrogate
} else {
// U+0800 a U+FFFF: 3 bytes
length += 3. }
}
return length. }
}
Embora essa abordagem seja rápida e evite a alocação de memória desnecessária, ela tem suas limitações:
Para garantir que sua implementação funciona corretamente, crie testes unitários cobrindo diferentes intervalos de caracteres, incluindo ASCII, caracteres de BMP, e fora do BMP com pares de surrogates. Assim, você consegue verificar se a contagem bate com o resultado de getBytes("UTF-8") para exemplos variados. A decisão fica mais saudável quando o time consegue medir o impacto depois. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta.
Saber o tamanho de uma string em UTF-8 sem codificá-la toda poupa recursos em sistemas de alta performance, streaming ou comunicação. A implementação apresentada é uma solução prática que pode ser adaptada às necessidades específicas, sempre considerando suas limitações de validação e cobertura de casos extremos. Sem esse critério, a solução pode parecer simples no começo e cara no suporte. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. Esse contexto ajuda a separar ganho real de novidade difícil de sustentar. A decisão fica mais saudável quando o time consegue medir o impacto depois.
Se sua aplicação exige uma análise mais robusta ou suporte a strings mal formadas, é interessante combinar essa abordagem com validações adicionais ou usar bibliotecas específicas de manipulação Unicode. Assim, você garante eficiência sem perder a confiabilidade na sua lógica de serialização. O valor aparece melhor quando operação, produto e engenharia olham para o mesmo risco. Por isso, o recorte precisa considerar manutenção, validação e caminho de volta. A decisão fica mais saudável quando o time consegue medir o impacto depois. A decisão fica mais saudável quando o time consegue medir o impacto depois. A decisão fica mais saudável quando o time consegue medir o impacto depois.
Carregando comentários...