1054 votes

Comment convertir un octet UTF-8[] en chaîne de caractères ?

J'ai un byte[] qui est chargé à partir d'un fichier dont je sais par hasard qu'il contient UTF-8 .

Dans un code de débogage, j'ai besoin de le convertir en chaîne. Existe-t-il un langage unique qui permette de le faire ?

Sous les couvertures, il devrait y avoir juste une allocation et une memcopy Ainsi, même si elle n'est pas mise en œuvre, elle devrait être possible.

7 votes

"devrait être juste une allocation et un memcopy" : n'est pas correct parce qu'une chaîne .NET est encodée en UTF-16. Un caractère Unicode peut être une unité de code UTF-8 ou une unité de code UTF-16. Un autre peut être deux unités de code UTF-8 ou une unité de code UTF-16, un autre peut être trois unités de code UTF-8 ou une unité de code UTF-16, un autre peut être quatre unités de code UTF-8 ou deux unités de code UTF-16. Un memcopy pourrait être capable d'élargir mais il ne serait pas capable de gérer la conversion UTF-8 vers UTF-16.

1640voto

Zanoni Points 8401
string result = System.Text.Encoding.UTF8.GetString(byteArray);

17 votes

Comment gère-t-il les chaînes de caractères sans fin ?

18 votes

@maazza pour une raison inconnue, ça ne marche pas du tout. Je l'appelle comme System.Text.Encoding.UTF8.GetString(buf).TrimEnd('\0'); .

20 votes

@Hi-Angel Une raison inconnue ? La seule raison pour laquelle les chaînes à terminaison nulle sont devenues populaires est le langage C - et même cela n'était qu'à cause d'une bizarrerie historique (les instructions du CPU qui traitaient les chaînes à terminaison nulle). .NET n'utilise les chaînes à terminaison nulle que lors de l'interopérabilité avec du code qui utilise des chaînes à terminaison nulle (qui sont enfin disparaissant). Il est tout à fait possible qu'une chaîne de caractères contienne des caractères NUL. Et bien sûr, alors que les chaînes à terminaison nulle sont très simples en ASCII (il suffit de construire jusqu'à ce que vous obteniez le premier octet zéro), d'autres codages, y compris UTF-8, ne sont pas aussi simples.

357voto

detale Points 2047

Il y a au moins quatre façons différentes de faire cette conversion.

  1. GetString de l'encodage
    mais vous ne pourrez pas récupérer les octets originaux si ces octets contiennent des caractères non ASCII.

  2. BitConverter.ToString
    La sortie est une chaîne délimitée par des "-", mais il n'existe pas de méthode intégrée à .NET pour reconvertir la chaîne en tableau d'octets.

  3. Convert.ToBase64Stringing
    Vous pouvez facilement reconvertir la chaîne de sortie en tableau d'octets en utilisant Convert.FromBase64String .
    Remarque : la chaîne de sortie peut contenir '+', '/' et '='. Si vous voulez utiliser la chaîne dans une URL, vous devez la coder explicitement.

  4. HttpServerUtility.UrlTokenEncode
    Vous pouvez facilement reconvertir la chaîne de sortie en tableau d'octets en utilisant HttpServerUtility.UrlTokenDecode . La chaîne de sortie est déjà compatible avec les URL ! L'inconvénient est qu'il faut System.Web assemblage si votre projet n'est pas un projet web.

Un exemple complet :

byte[] bytes = { 130, 200, 234, 23 }; // A byte array contains non-ASCII (or non-readable) characters

string s1 = Encoding.UTF8.GetString(bytes); // 
byte[] decBytes1 = Encoding.UTF8.GetBytes(s1);  // decBytes1.Length == 10 !!
// decBytes1 not same as bytes
// Using UTF-8 or other Encoding object will get similar results

string s2 = BitConverter.ToString(bytes);   // 82-C8-EA-17
String[] tempAry = s2.Split('-');
byte[] decBytes2 = new byte[tempAry.Length];
for (int i = 0; i < tempAry.Length; i++)
    decBytes2[i] = Convert.ToByte(tempAry[i], 16);
// decBytes2 same as bytes

string s3 = Convert.ToBase64String(bytes);  // gsjqFw==
byte[] decByte3 = Convert.FromBase64String(s3);
// decByte3 same as bytes

string s4 = HttpServerUtility.UrlTokenEncode(bytes);    // gsjqFw2
byte[] decBytes4 = HttpServerUtility.UrlTokenDecode(s4);
// decBytes4 same as bytes

7 votes

LINQ it : var decBytes2 = str.Split('-').Select(ch => Convert.ToByte(ch, 16)).ToArray();

0 votes

Ceci devrait être la réponse acceptée. Elle illustre parfaitement le résultat de plusieurs méthodes. La réponse acceptée actuelle n'en montre qu'une seule, ce qui peut être problématique pour certains développeurs qui ne font pas défiler les pages aussi loin. - à moins que vous ne triiez par les votes, bien sûr.

19voto

Timbo Points 14117
string str = System.Text.Encoding.UTF8.GetString( arr );

11voto

z-boss Points 4033
byte[] b = new byte[100];
string s = System.Text.UTF8Encoding.UTF8.GetString(b);

9voto

Daniel Brückner Points 36242
String text = System.Text.Encoding.UTF8.GetString(bytes);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X