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

У меня есть byte[]массив, который загружается из файла, который, как мне известно, содержит UTF-8 .

В некотором отладочном коде мне нужно преобразовать его в строку. Есть ли один лайнер, который сделает это?

Под обложками должно быть только выделение и мемкопия , поэтому даже если это не реализовано, это должно быть возможно.

16.06.2009 18:47:00
«должно быть просто выделением и записью»: неверно, потому что строка .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.
Tom Blodget 19.11.2016 01:01:25
14 ОТВЕТОВ
РЕШЕНИЕ
string result = System.Text.Encoding.UTF8.GetString(byteArray);
1453
12.02.2015 20:19:13
как он обрабатывает строки с нулевым окончанием?
maazza 12.05.2015 12:43:37
@maazza по неизвестной причине это не так. Я называю это как System.Text.Encoding.UTF8.GetString(buf).TrimEnd('\0');.
Hi-Angel 27.07.2015 07:53:28
@ Привет-Ангел Неизвестная причина? Единственной причиной, по которой строки с нулевым символом в конце стали когда-либо популярными, был язык C - и даже это было только из-за исторической странности (инструкции CPU, которые имели дело со строками с нулевым символом в конце). .NET использует только строки с нулевым символом в конце при взаимодействии с кодом, который использует строки с нулевым символом в конце (которые в конечном итоге исчезают). Вполне допустимо, чтобы строка содержала NUL-символы. И, конечно же, в то время как строки с нулевым символом в ASCII очень просты (просто строите, пока не получите первый нулевой байт), другие кодировки, включая UTF-8, не так просты.
Luaan 23.11.2015 10:05:42
Одна из прекрасных особенностей UTF-8 заключается в том, что более короткая последовательность никогда не является подпоследовательностью более длинной последовательности. Таким образом, строка UTF-8 с нулевым символом в конце проста.
plugwash 24.11.2015 17:00:36
Что ж, удачи в распаковке, если у него нет ascii. Просто используйте Convert.ToBase64String.
Erik Bergstedt 12.12.2015 10:30:20

Есть как минимум четыре разных способа сделать это преобразование.

  1. Кодирует GetString
    , но вы не сможете вернуть исходные байты, если эти байты имеют символы не ASCII.

  2. BitConverter.ToString Выходными данными
    является строка с разделителями «-», но нет встроенного метода .NET для преобразования строки обратно в байтовый массив.

  3. Convert.ToBase64String
    Вы можете легко преобразовать выходную строку обратно в байтовый массив, используя Convert.FromBase64String.
    Примечание. Выходная строка может содержать «+», «/» и «=». Если вы хотите использовать строку в URL, вам необходимо явно ее кодировать.

  4. HttpServerUtility.UrlTokenEncode
    Вы можете легко преобразовать выходную строку обратно в байтовый массив, используя HttpServerUtility.UrlTokenDecode. Выходная строка уже совместима с URL! Недостатком является необходимость System.Webсборки, если ваш проект не является веб-проектом.

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

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
321
29.07.2017 02:32:37
LINQ it:var decBytes2 = str.Split('-').Select(ch => Convert.ToByte(ch, 16)).ToArray();
drtf 13.07.2014 14:43:03

Определение:

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

С помощью:

string result = input.ConvertByteToString();
12
1.08.2015 20:56:52

Использование (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;
    }

}
7
29.11.2015 16:44:16

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

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

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

    return response;
}
8
29.06.2015 07:42:31
Я получил System.FormatException, используя ваш метод, когда распаковал его с Convert.FromBase64String.
Erik Bergstedt 12.12.2015 10:20:56
@ AndrewJE это займет даже для вычисления, если у вас есть большой массив байтов, как тот, который используется на рисунках.
user3841581 4.11.2017 16:55:07

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

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

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
4
18.05.2015 13:38:41
Но не UTF-8 метинкс?
david.pfx 14.07.2015 10:36:31
UnicodeEncodingсамое плохое имя класса в мире; Юникод вообще не является кодировкой. Этот класс на самом деле UTF-16. Версия с прямым порядком байтов, я думаю.
Nyerguds 17.11.2016 08:16:18

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

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

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

 var byteStr = Convert.ToBase64String(bytes);
3
15.09.2016 05:55:06

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

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

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

2
17.11.2016 08:24:19

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

var convertedString = BitConverter.ToString(byteAttay);

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

2
5.01.2017 10:53:30
Это преобразует массив байтов в шестнадцатеричную строку, представляющую каждый байт, что обычно не то, что вы хотите при преобразовании байтов в строку. Если да, то это другой вопрос, см., Например, Как преобразовать массив байтов в шестнадцатеричную строку и наоборот? ,
CodeCaster 5.01.2017 10:59:00
Не то, что спросил ОП
Winter 19.07.2017 13:46:34

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

// 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[]массив как массив строк с нулевым символом в конце. Это может быть безопасно проигнорировано в простом случае

2
29.06.2017 00:24:18
Мой, на самом деле. byteArr.TakeWhile(x => x != 0)это быстрый и простой способ решить проблему нулевого завершения.
Nyerguds 21.09.2017 09:11:02

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);
        }
1
6.07.2018 13:27:53
не было одного. Но эта функция используется для двоичной передачи в нашей корпоративной сети, и до сих пор 20TB были правильно и повторно закодированы. Так что для меня эта функция работает :)
Marco Pardo 17.09.2018 19:10:17

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

string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length);
1
21.02.2019 16:38:04

Попробуйте это консольное приложение:

static void Main(string[] args)
{
    //Encoding _UTF8 = Encoding.UTF8;
    string[] _mainString = { "Héllo World" };
    Console.WriteLine("Main String: " + _mainString);

    //Convert a string to utf-8 bytes.
    byte[] _utf8Bytes = Encoding.UTF8.GetBytes(_mainString[0]);

    //Convert utf-8 bytes to a string.
    string _stringuUnicode = Encoding.UTF8.GetString(_utf8Bytes);
    Console.WriteLine("String Unicode: " + _stringuUnicode);
}
0
29.09.2019 07:49:57