web-dev-qa-db-fra.com

Pourquoi .net utilise le codage UTF16 pour la chaîne, mais utilise utf8 par défaut pour enregistrer les fichiers?

d'ici

Essentiellement, la chaîne utilise le formulaire de codage de caractères UTF-16

Mais lors de l'enregistrement vs StreamWriter :

Ce constructeur crée un StreamWriter avec le codage UTF-8 sans une marque d'ordre des octets (BOM),

J'ai vu cet exemple (lien brisé supprimé):

enter image description here

Et ça ressemble à utf8 est plus petit pour certaines chaînes tandis que utf-16 est plus petit dans certaines autres chaînes.

  • Alors pourquoi .net utilise utf16 comme codage par défaut pour la chaîne tandis que utf8 pour enregistrer le fichier?

Merci.

p.s. J'ai déjà lu le fameux article

58
Royi Namir

Si vous êtes heureux d'ignorer les paires de substitution (ou de manière équivalente, la possibilité que votre application ait besoin de caractères en dehors du plan multilingue de base), UTF-16 a quelques belles propriétés, essentiellement parce qu'il faut toujours deux octets par code unité et représentant tous les caractères BMP dans une seule unité de code chacun.

Considérez le type primitif char. Si nous utilisons UTF-8 comme représentation en mémoire et que nous voulons gérer tous les caractères Unicode, quelle devrait être la taille? Cela peut aller jusqu'à 4 octets ... ce qui signifie que nous devons toujours allouer 4 octets. À ce stade, nous pourrions aussi bien utiliser UTF-32!

Bien sûr, nous pourrions utiliser UTF-32 comme représentation char, mais UTF-8 dans la représentation string, en convertissant au fur et à mesure.

Les deux inconvénients de l'UTF-16 sont:

  • Le nombre d'unités de code par caractère Unicode est variable, car tous les caractères ne sont pas dans le BMP. Jusqu'à ce que les emoji deviennent populaires, cela n'affectait pas de nombreuses applications au quotidien. De nos jours, certainement pour les applications de messagerie et autres, les développeurs utilisant UTF-16 ont vraiment besoin de connaître les paires de substitution.
  • Pour le simple ASCII (qui est beaucoup de texte, au moins à l'ouest), cela prend deux fois l'espace du texte codé UTF-8 équivalent.

(En guise de remarque, je crois que Windows utilise UTF-16 pour les données Unicode, et il est logique que .NET emboîte le pas pour des raisons d'interopérabilité. Cela ne fait que pousser la question en une seule étape.)

Compte tenu des problèmes des paires de substitution, je soupçonne que si une langue/plate-forme était conçue à partir de zéro sans exigences d'interopérabilité (mais en basant sa gestion de texte en Unicode), UTF-16 ne serait pas le meilleur choix. Soit UTF-8 (si vous voulez l'efficacité de la mémoire et ne vous occupez pas d'une certaine complexité de traitement en termes d'accès au nième caractère) ou UTF-32 (l'inverse) serait un meilleur choix. (Même arriver au nième caractère a des "problèmes" en raison de choses comme différentes formes de normalisation. Le texte est difficile ...)

49
Jon Skeet

Comme pour de nombreuses questions "pourquoi cela a-t-il été choisi", cela a été déterminé par l'histoire. Windows est devenu un système d'exploitation Unicode à sa base en 1993. À l'époque, Unicode n'avait encore qu'un espace de code de 65535 points de code, appelés de nos jours UCS. Ce n'est qu'en 1996 qu'Unicode a acquis les avions supplémentaires pour étendre l'espace de codage à un million de points de code. Et remplacez les paires pour les adapter à un codage 16 bits, définissant ainsi la norme utf-16.

Les chaînes .NET sont utf-16 car c'est un excellent ajustement avec le codage du système d'exploitation, aucune conversion n'est requise.

L'histoire de l'utf-8 est plus trouble. Certainement après Windows NT, la RFC-3629 date de novembre 1993. Il a fallu un certain temps pour prendre pied, Internet a joué un rôle déterminant.

26
Hans Passant

UTF-8 est la valeur par défaut pour le stockage et le transfert de texte car c'est une forme relativement compacte pour la plupart des langues (certaines langues sont plus compactes en UTF-16 qu'en UTF-8). Chaque langue spécifique a un encodage plus efficace.

UTF-16 est utilisé pour les chaînes en mémoire car il est plus rapide par caractère à analyser et mappe directement à la classe de caractères Unicode et à d'autres tables. Toutes les fonctions de chaîne dans Windows utilisent UTF-16 et existent depuis des années.

10
user2457603