it-swarm.dev

Por que .net usa a codificação UTF16 para string, mas usa utf8 como padrão para salvar arquivos?

daqui

Essencialmente, a string usa o formulário de codificação de caracteres UTF-16

Mas ao salvar vs StreamWriter :

Esse construtor cria um StreamWriter com codificação UTF-8 sem uma Byte-Order Mark (BOM),

Eu vi este exemplo (link quebrado removido):

enter image description here

E parece que utf8 é menor para algumas strings enquanto utf-16 é menor em algumas outras strings.

  • Então, por que .net usa utf16 como codificação padrão para string enquanto utf8 para salvar o arquivo?

Obrigado.

p. Eu já li o famoso artigo

58
Royi Namir

Se você está feliz por ignorar pares substitutos (ou equivalentemente, a possibilidade de seu aplicativo precisar de caracteres fora do Plano Multilíngue Básico), o UTF-16 possui algumas propriedades agradáveis, basicamente por sempre exigir dois bytes por código unidade e representando todos os caracteres BMP em uma única unidade de código cada.

Considere o tipo primitivo char. Se usarmos UTF-8 como representação na memória e quisermos lidar com todos caracteres Unicode, qual deve ser o tamanho? Pode ter até 4 bytes ... o que significa que sempre teríamos que alocar 4 bytes. Nesse ponto, podemos usar o UTF-32!

Obviamente, poderíamos usar UTF-32 como a representação char, mas UTF-8 na representação string, convertendo à medida que avançamos.

As duas desvantagens do UTF-16 são:

  • O número de unidades de código por caractere Unicode é variável, porque nem todos os caracteres são no BMP. Até o emoji se tornar popular, isso não afetava muitos aplicativos no uso diário. Hoje em dia, certamente para aplicativos de mensagens e afins, os desenvolvedores que usam UTF-16 realmente precisam conhecer pares substitutos.
  • Para simples ASCII (que tem muito texto, pelo menos no oeste)) ocupa duas vezes o espaço do texto codificado UTF-8 equivalente.

(Como uma observação lateral, acredito que o Windows usa UTF-16 para dados Unicode, e faz sentido que o .NET siga o exemplo por razões de interoperabilidade. Isso apenas coloca a questão em uma etapa.)

Dados os problemas dos pares substitutos, eu suspeito que se uma linguagem/plataforma estivesse sendo projetada do zero sem requisitos de interoperabilidade (mas baseando seu tratamento de texto em Unicode), o UTF-16 não seria a melhor escolha. Ou UTF-8 (se você quer eficiência de memória e não se importa com a complexidade do processamento em termos de chegar ao enésimo caractere) ou UTF-32 (ao contrário) seria uma escolha melhor. (Mesmo chegar ao enésimo caractere tem "problemas" devido a coisas como diferentes formas de normalização. O texto é difícil ...)

49
Jon Skeet

Como em muitas perguntas "por que isso foi escolhido", isso foi determinado pela história. O Windows se tornou um sistema operacional Unicode em sua essência em 1993. Naquela época, o Unicode ainda possuía um espaço de código de 65535 pontos de código, atualmente chamado UCS. Não foi até 1996, até a Unicode adquirir os planos suplementares para estender o espaço de codificação para um milhão de pontos de código. E pares substitutos para ajustá-los a uma codificação de 16 bits, definindo assim o padrão utf-16.

As strings do .NET são utf-16 porque esse é um excelente ajuste com a codificação do sistema operacional; nenhuma conversão é necessária.

A história do utf-8 é mais sombria. Definitivamente passado o Windows NT, a RFC-3629 data de novembro de 1993. Demorou um pouco para se manter firme, a Internet foi fundamental.

26
Hans Passant

UTF-8 é o padrão para armazenamento e transferência de texto, pois é uma forma relativamente compacta para a maioria dos idiomas (alguns idiomas são mais compactos em UTF-16 do que em UTF-8). Cada idioma específico possui uma codificação mais eficiente.

O UTF-16 é usado para seqüências de caracteres na memória porque é mais rápido analisar por caractere e mapeia diretamente para a classe de caracteres unicode e outras tabelas. Todas as funções de cadeia de caracteres no Windows usam UTF-16 e existem há anos.

10
user2457603