Jak przekonwertować UTF-8 bajt [] na string?

Mam byte[] tablicę, która jest ładowana z pliku, który przypadkiem zawiera UTF-8. W niektórych kod debugowania, muszę przekonwertować go na ciąg znaków. Czy jest jeden liner, który to zrobi?

Pod okładkami powinna być tylko alokacja i memcopy , więc nawet jeśli nie jest zaimplementowana, powinna być możliwa.

Author: Raedwald, 2009-06-16

13 answers

string result = System.Text.Encoding.UTF8.GetString(byteArray);
 1232
Author: Zanoni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 20:19:13

Są co najmniej cztery różne sposoby na tę konwersję.

  1. Encoding ' s GetString
    , ale nie będziesz w stanie odzyskać oryginalnych bajtów, jeśli te bajty mają znaki inne niż ASCII.

  2. BitConverter.ToString
    wyjście jest rozdzielonym łańcuchem" -", ale nie ma wbudowanej metody. NET do konwersji łańcucha z powrotem do tablicy bajtów.

  3. Nawróć się.ToBase64String
    możesz łatwo przekonwertować wyjście łańcuch z powrotem do tablicy bajtów za pomocą Convert.FromBase64String.
    Uwaga: wyjściowy ciąg znaków może zawierać '+', ' / 'i'='. Jeśli chcesz użyć ciągu w adresie URL, musisz go jawnie zakodować.

  4. HttpServerUtility.UrlTokenEncode
    możesz łatwo przekonwertować łańcuch wyjściowy z powrotem do tablicy bajtów za pomocą HttpServerUtility.UrlTokenDecode. Wyjściowy ciąg jest już przyjazny URL! Minusem jest to, że potrzebuje System.Web assembly, jeśli twój projekt nie jest projektem webowym.

Pełny przykład:

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
 277
Author: detale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-29 02:32:37

Ogólne rozwiązanie do konwersji z tablicy bajtów na ciąg znaków, gdy nie znasz kodowania:

static string BytesToStringConverted(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        using (var streamReader = new StreamReader(stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}
 21
Author: Nir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-22 14:31:45

Definicja:

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

Użycie:

string result = input.ConvertByteToString();
 12
Author: Erçin Dedeoğlu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-01 20:56:52

Konwersja byte[] na string wydaje się prosta, ale każdy rodzaj kodowania może zepsuć wyjściowy ciąg. Ta mała funkcja działa bez żadnych nieoczekiwanych rezultatów:

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

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

    return response;
}
 9
Author: AndrewJE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-29 07:42:31

Using (byte)b.ToString("x2"), Outputs 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
Author: metadings,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-29 16:44:16

Istnieje również Klasa UnicodeEncoding, dość prosta w użyciu:

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

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
 5
Author: P.K.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-18 13:38:41

Alternatywnie:

 var byteStr = Convert.ToBase64String(bytes);
 2
Author: Fehr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-15 05:55:06

Jednowiersz Linq do konwersji tablicy bajtów byteArrFilename odczytywanej z pliku na czysty łańcuch zakończony znakiem C w stylu ascii byłby taki: przydatny do czytania rzeczy takich jak tabele indeksów plików w starych formatach archiwów.

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

Używam '?' jako domyślnego znaku dla wszystkiego, co nie jest czystym ascii, ale można to oczywiście zmienić. Jeśli chcesz mieć pewność, że możesz go wykryć, po prostu użyj '\0' zamiast tego, ponieważ TakeWhile na początku zapewnia, że łańcuch zbudowany w ten sposób nie może zawierać '\0' wartości z źródło wejścia.

 2
Author: Nyerguds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-17 08:24:19

BitConverter klasa może być użyta do konwersji byte[] na string.

var convertedString = BitConverter.ToString(byteAttay);

Dokumentacja klasy {[1] } może być zapisana na MSDN

 2
Author: Sagar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 10:53:30

Według mojej wiedzy żadna z podanych odpowiedzi nie gwarantuje poprawnego zachowania z zerowym zakończeniem. Dopóki ktoś nie pokaże mi inaczej, napisałem własną klasę statyczną do obsługi tego za pomocą następujących metod:

// 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);
}

Powodem startIndex był przykład, nad którym pracowałem, a konkretnie potrzebowałem przetworzyć byte[] jako tablicę zakończonych znakiem null łańcuchów. Można go bezpiecznie zignorować w prostym przypadku

 2
Author: Assimilater,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 00:24:18

Spróbuj tego:

string myresult = System.Text.Encoding.UTF8.GetString(byteArray);
 0
Author: William Lasiewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-29 06:56:45

Hier jest wynikiem, w którym nie trzeba było zadawać sobie trudu z kodowaniem. Używałem go w mojej klasie sieciowej i wysyłałem z nim obiekty binarne jako ciąg znaków.

        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
Author: Marco Pardo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 13:27:53