web-dev-qa-db-fra.com

Comment convertir UTF-8 octet [] en chaîne?

J'ai un tableau byte[] qui est chargé à partir d'un fichier que je connais contient UTF-8 . Dans certains codes de débogage, je dois le convertir en chaîne. Y a-t-il un seul paquebot qui fera cela? 

Sous les couvertures, cela devrait être juste une allocation et une memcopy, donc même si cela n’est pas implémenté, cela devrait être possible.

810
BCS
string result = System.Text.Encoding.UTF8.GetString(byteArray);
1299
Zanoni

Il existe au moins quatre manières différentes d'effectuer 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 "-", mais il n'existe pas de méthode intégrée .NET pour convertir la chaîne en tableau d'octets.

  3. Convert.ToBase64String
    Vous pouvez facilement reconvertir la chaîne de sortie en tableau d'octets à l'aide de Convert.FromBase64String.
    Remarque: La chaîne de sortie peut contenir '+', '/' et '='. Si vous souhaitez utiliser la chaîne dans une URL, vous devez l'encoder explicitement.

  4. HttpServerUtility.UrlTokenEncode
    Vous pouvez facilement reconvertir la chaîne de sortie en tableau d'octets à l'aide de HttpServerUtility.UrlTokenDecode. La chaîne de sortie est déjà adaptée aux URL! L'inconvénient est qu'il a besoin de System.Web Assembly 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
292
detale

Une solution générale pour convertir un tableau d'octets en chaîne lorsque vous ne connaissez pas l'encodage: 

static string BytesToStringConverted(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        using (var streamReader = new StreamReader(stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}
21
Nir

Définition:

public static string ConvertByteToString(this byte[] source)
{
    return source != null ? System.Text.Encoding.UTF8.GetString(source) : null;
}

En utilisant:

string result = input.ConvertByteToString();
12
Erçin Dedeoğlu

Convertir un byte[] en string semble simple, mais tout type d’encodage risque de gâcher la chaîne de sortie. Cette petite fonction fonctionne sans aucun résultat inattendu: 

private string ToString(byte[] bytes)
{
    string response = string.Empty;

    foreach (byte b in bytes)
        response += (Char)b;

    return response;
}
9
AndrewJE

Utilisation de (byte)b.ToString("x2"), sorties b4b5dfe475e58b67

public static class Ext {

    public static string ToHexString(this byte[] hex)
    {
        if (hex == null) return null;
        if (hex.Length == 0) return string.Empty;

        var s = new StringBuilder();
        foreach (byte b in hex) {
            s.Append(b.ToString("x2"));
        }
        return s.ToString();
    }

    public static byte[] ToHexBytes(this string hex)
    {
        if (hex == null) return null;
        if (hex.Length == 0) return new byte[0];

        int l = hex.Length / 2;
        var b = new byte[l];
        for (int i = 0; i < l; ++i) {
            b[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
        }
        return b;
    }

    public static bool EqualsTo(this byte[] bytes, byte[] bytesToCompare)
    {
        if (bytes == null && bytesToCompare == null) return true; // ?
        if (bytes == null || bytesToCompare == null) return false;
        if (object.ReferenceEquals(bytes, bytesToCompare)) return true;

        if (bytes.Length != bytesToCompare.Length) return false;

        for (int i = 0; i < bytes.Length; ++i) {
            if (bytes[i] != bytesToCompare[i]) return false;
        }
        return true;
    }

}
8
metadings

Il y a aussi la classe UnicodeEncoding, d'utilisation assez simple:

ByteConverter = new UnicodeEncoding();
string stringDataForEncoding = "My Secret Data!";
byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding);

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
5
P.K.

Alternativement:

 var byteStr = Convert.ToBase64String(bytes);
2
Fehr

À ma connaissance, aucune des réponses fournies ne garantit un comportement correct avec une terminaison nulle. Jusqu'à ce que quelqu'un me montre différemment, j'ai écrit ma propre classe statique pour le gérer à l'aide des méthodes suivantes:

// Mimics the functionality of strlen() in c/c++
// Needed because niether StringBuilder or Encoding.*.GetString() handle \0 well
static int StringLength(byte[] buffer, int startIndex = 0)
{
    int strlen = 0;
    while
    (
        (startIndex + strlen + 1) < buffer.Length // Make sure incrementing won't break any bounds
        && buffer[startIndex + strlen] != 0       // The typical null terimation check
    )
    {
        ++strlen;
    }
    return strlen;
}

// This is messy, but I haven't found a built-in way in c# that guarentees null termination
public static string ParseBytes(byte[] buffer, out int strlen, int startIndex = 0)
{
    strlen = StringLength(buffer, startIndex);
    byte[] c_str = new byte[strlen];
    Array.Copy(buffer, startIndex, c_str, 0, strlen);
    return Encoding.UTF8.GetString(c_str);
}

La raison de startIndex était dans l'exemple sur lequel je travaillais spécifiquement que je devais analyser un byte[] sous la forme d'un tableau de chaînes terminées par un caractère null. Il peut être ignoré en toute sécurité dans le cas simple

2
Assimilater

La classe BitConverter peut être utilisée pour convertir un byte[] en string.

var convertedString = BitConverter.ToString(byteAttay);

La documentation de la classe BitConverter peut être installée sur MSDN

2
Sagar

Une ligne linéaire Linq permettant de convertir un tableau d'octets byteArrFilename lu à partir d'un fichier en une chaîne zéro à terminaison de style C pur ascii serait la suivante: Pratique pour lire des éléments tels que les tables d'index de fichiers dans d'anciens formats d'archives.

String filename = new String(byteArrFilename.TakeWhile(x => x != 0)
                              .Select(x => x < 128 ? (Char)x : '?').ToArray());

J'utilise '?' comme caractère par défaut pour tout ce qui n'est pas pur ascii ici, mais cela peut être modifié, bien sûr. Si vous voulez être sûr de pouvoir le détecter, utilisez plutôt '\0', car la variable TakeWhile au début garantit qu'une chaîne construite de cette manière ne peut pas contenir les valeurs '\0' de la source d'entrée.

2
Nyerguds

En plus de la réponse sélectionnée, si vous utilisez .NET35 ou .NET35 CE, vous devez spécifier l'index du premier octet à décoder et le nombre d'octets à décoder:

string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length);
0
The One

hier est un résultat où vous n'avez pas à vous soucier de l'encodage. Je l'ai utilisé dans ma classe de réseau et j'envoie des objets binaires sous forme de chaîne.

        public static byte[] String2ByteArray(string str)
        {
            char[] chars = str.ToArray();
            byte[] bytes = new byte[chars.Length * 2];

            for (int i = 0; i < chars.Length; i++)
                Array.Copy(BitConverter.GetBytes(chars[i]), 0, bytes, i * 2, 2);

            return bytes;
        }

        public static string ByteArray2String(byte[] bytes)
        {
            char[] chars = new char[bytes.Length / 2];

            for (int i = 0; i < chars.Length; i++)
                chars[i] = BitConverter.ToChar(bytes, i * 2);

            return new string(chars);
        }
0
Marco Pardo

Essaye ça:

string myresult = System.Text.Encoding.UTF8.GetString(byteArray);
0
Bill