Как преобразовать UTF-8 byte [] в строку?

у меня естьbyte[] Массив, который загружается из файла, с которым я случайно познакомился, содержитUTF-8,, В некотором отладочном коде мне нужно преобразовать его в строку. Есть ли один лайнер, который сделает это?

Под крышками это должно быть только выделение иmemcopy, так что даже если это не реализовано, это должно быть возможно.

 Tom Blodget19 нояб. 2016 г., 02:01
"должно быть просто выделением, а memcopy": неверно, поскольку строка .NET имеет кодировку UTF-16. Символ Unicode может быть одной кодовой единицей UTF-8 или одной кодовой единицей UTF-16. другая может быть двумя кодовыми единицами UTF-8 или одной кодовой единицей UTF-16, другая может быть тремя кодовыми единицами UTF-8 или одной кодовой единицей UTF-16, другая может быть четырьмя кодовыми единицами UTF-8 или двумя кодовыми единицами UTF-16 , Memcopy может быть в состоянии расширяться, но он не сможет обрабатывать преобразование UTF-8 в UTF-16.

Ответы на вопрос(14)

В качестве альтернативы:

 var byteStr = Convert.ToBase64String(bytes);

В дополнение к выбранному ответу, если вы используете .NET35 или .NET35 CE, вы должны указать индекс первого байта для декодирования и количество байтов для декодирования:

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

Преобразованиеbyte[] кstring кажется простым, но любой вид кодирования может испортить выходную строку. Эта маленькая функция просто работает без каких-либо неожиданных результатов:

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

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

    return response;
}
 12 дек. 2015 г., 11:20
Я получил System.FormatException, используя ваш метод, когда распаковал его с Convert.FromBase64String.
 04 нояб. 2017 г., 17:55
@ AndrewJE это займет даже для вычисления, если у вас есть большой массив байтов, как тот, который используется на рисунках.

Общее решение для преобразования байтового массива в строку, когда вы не знаете кодировку:

static string BytesToStringConverted(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
        using (var streamReader = new StreamReader(stream))
        {
            return streamReader.ReadToEnd();
        }
    }
}
 26 сент. 2017 г., 19:05
Но это предполагает, что в байтовом потоке есть либо кодирующая спецификация, либо что она находится в UTF-8. Но вы можете сделать то же самое с кодировкой в любом случае. Это волшебным образом не решает проблему, когда вы не знаете кодировку.

Существует по меньшей мере четыре различных способа сделать это преобразование.

Encoding's GetString
, but you won't be able to get the original bytes back if those bytes have non-ASCII characters.

BitConverter.ToString
The output is a "-" delimited string, but there's no .NET built-in method to convert the string back to byte array.

Convert.ToBase64String
You can easily convert the output string back to byte array by using Convert.FromBase64String.
Note: The output string could contain '+', '/' and '='. If you want to use the string in a URL, you need to explicitly encode it.

HttpServerUtility.UrlTokenEncode
You can easily convert the output string back to byte array by using HttpServerUtility.UrlTokenDecode. The output string is already URL friendly! The downside is it needs System.Web assembly if your project is not a web project.

Полный пример:

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
 13 июл. 2014 г., 16:43
LINQ это:var decBytes2 = str.Split('-').Select(ch => Convert.ToByte(ch, 16)).ToArray();

Линк Linq для преобразования байтового массиваbyteArrFilename чтение из файла в чистую строку с нулевым окончанием в стиле ascii C было бы следующим: Удобно для чтения таких вещей, как таблицы индексов файлов в старых форматах архивов.

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

я использую'?' по умолчанию char для чего-то не чистого ascii здесь, но это можно изменить, конечно. Если вы хотите быть уверены, что можете обнаружить это, просто используйте'\0' вместо этого, так какTakeWhile в начале гарантирует, что строка, построенная таким образом, не может содержать'\0' значения из входного источника.

hier - это результат, когда вам не нужно было беспокоиться о кодировке. Я использовал его в своем сетевом классе и отправлял двоичные объекты в виде строки с ним.

        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);
        }
 16 сент. 2018 г., 20:10
Где твой юнит тест?)?
 17 сент. 2018 г., 21:10
не было одного. Но эта функция используется для двоичной передачи в нашей корпоративной сети, и до сих пор 20 ТБ были повторно и правильно закодированы. Так что для меня эта функция работает :)

Насколько мне известно, ни один из приведенных ответов не гарантирует правильного поведения с нулевым завершением. Пока кто-то не показывает мне по-другому, я написал свой собственный статический класс для обработки этого с помощью следующих методов:

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

Причина дляstartIndex был в примере, над которым я работал конкретно мне нужно было разобратьbyte[] как массив строк с нулевым символом в конце. Это может быть безопасно проигнорировано в простом случае

 21 сент. 2017 г., 11:11
Мой, на самом деле.byteArr.TakeWhile(x => x != 0) это быстрый и простой способ решить проблему нулевого завершения.

Definition:

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

Using:

string result = input.ConvertByteToString();

С помощью(byte)b.ToString("x2")Выходы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;
    }

}

Попробуй это:

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

Существует также класс UnicodeEncoding, довольно простой в использовании:

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

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
 17 нояб. 2016 г., 09:16
UnicodeEncoding самое плохое имя класса когда-либо; Unicode вообще не является кодировкой. Этот класс на самом деле UTF-16. Версия с прямым порядком байтов, я думаю.
 14 июл. 2015 г., 12:36
Но не UTF-8 метинкс?
Решение Вопроса
string result = System.Text.Encoding.UTF8.GetString(byteArray);
 12 мая 2015 г., 14:43
как он обрабатывает строки с нулевым окончанием?
 27 июл. 2015 г., 09:53
@maazza по неизвестной причине, это совсем не так. Я так называюSystem.Text.Encoding.UTF8.GetString(buf).TrimEnd('\0');.
 24 нояб. 2015 г., 18:00
Одна из прекрасных особенностей UTF-8 состоит в том, что более короткая последовательность никогда не является подпоследовательностью более длинной последовательности. Таким образом, строка UTF-8 с нулевым символом в конце проста.
 23 нояб. 2015 г., 11:05
@ Привет-Ангел Неизвестная причина? Единственной причиной, по которой строки с нулевым символом в конце стали когда-либо популярными, был язык C - и даже это было связано только с исторической странностью (инструкции CPU, которые имели дело со строками с нулевым символом в конце). .NET использует только строки с нулевым символом в конце при взаимодействии с кодом, использующим строки с нулевым символом в конце (которыеfinally исчезают). Совершенно верно, что строка содержит NUL-символы. И, конечно же, в то время как строки с нулевым символом в ASCII очень просты (просто собирайте, пока не получите первый нулевой байт), другие кодировки, включая UTF-8, не так просты.
 12 дек. 2015 г., 11:30
Что ж, удачи в распаковке, если у него нет ascii. Просто используйте Convert.ToBase64String.

BitConverter класс может быть использован для преобразованияbyte[] вstring.

var convertedString = BitConverter.ToString(byteAttay);

ДокументацияBitConverter класс можно найти наMSDN

 19 июл. 2017 г., 15:46
Не то, что ОП спросил
 05 янв. 2017 г., 11:59
Это преобразует массив байтов в шестнадцатеричную строку, представляющую каждый байт, что обычно не то, что вы хотите при преобразовании байтов в строку. Если да, то это другой вопрос, см., Например,How do you convert Byte Array to Hexadecimal String, and vice versa?.

Ваш ответ на вопрос