Как конвертировать UTF-8 byte[] в строку?
У меня есть byte[] массив, который загружен из файла, который я знаю, содержит UTF-8. В некотором отладочном коде мне нужно преобразовать его в строку. Есть ли один лайнер, который сделает это?
под обложками это должно быть просто распределение и memcopy, так что даже если это не реализовано, это должно быть возможно.
13 ответов:
есть по крайней мере четыре различных способа сделать это преобразование.
кодировка GetString
, но вы не сможете вернуть исходные байты, если эти байты имеют символы, отличные от ASCII.BitConverter.ToString
вывод представляет собой строку с разделителями" -", но нет встроенного метода .NET для преобразования строки обратно в байт матрица.преобразовать.ToBase64String
вы можете легко преобразовать выходную строку обратно в массив байт с помощьюConvert.FromBase64String.
Примечание: выходная строка может содержать '+', ' / 'и'='. Если вы хотите использовать строку в URL-адресе, вам нужно явно кодировать ее.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
общее решение для преобразования массива байтов в строку, когда вы не знаете кодировку:
static string BytesToStringConverted(byte[] bytes) { using (var stream = new MemoryStream(bytes)) { using (var streamReader = new StreamReader(stream)) { return streamReader.ReadToEnd(); } } }
определение:
public static string ConvertByteToString(this byte[] source) { return source != null ? System.Text.Encoding.UTF8.GetString(source) : null; }использование:
string result = input.ConvertByteToString();
преобразование a
byte[]доstringкажется простым, но любой вид кодировки, скорее всего, испортит выходную строку. Эта маленькая функция просто работает без каких-либо неожиданных результатов:private string ToString(byte[] bytes) { string response = string.Empty; foreach (byte b in bytes) response += (Char)b; return response; }
используя
(byte)b.ToString("x2")выводитb4b5dfe475e58b67public 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; } }
существует также класс UnicodeEncoding, довольно простой в использовании:
ByteConverter = new UnicodeEncoding(); string stringDataForEncoding = "My Secret Data!"; byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding); Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
однострочный Linq для преобразования массива байтов
byteArrFilenameчтение из файла в чистую строку с нулевым завершением в стиле ascii C будет следующим: удобно для чтения таких вещей, как таблицы индексов файлов в старых архивных форматах.String filename = new String(byteArrFilename.TakeWhile(x => x != 0) .Select(x => x < 128 ? (Char)x : '?').ToArray());Я использую
'?'как символ по умолчанию для чего-либо не чистого ascii здесь, но это можно изменить, конечно. Если вы хотите быть уверены, что вы можете обнаружить его, просто используйте СTakeWhileв начале гарантирует, что строка, построенная таким образом, не может быть содержать''значения из входного источника.
BitConverterкласс может быть использован для преобразованияbyte[]доstring.var convertedString = BitConverter.ToString(byteAttay);документация
BitConverterкласс может быть fount на MSDN
насколько мне известно, ни один из приведенных ответов не гарантирует правильного поведения с нулевым завершением. Пока кто-то не покажет мне по-другому, я написал свой собственный статический класс для обработки этого следующими методами:
// Mimics the functionality of strlen() in c/c++ // Needed because niether StringBuilder or Encoding.*.GetString() handle 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был в Примере, над которым я работал специально, мне нужно было разобрать abyte[]как массив строк, завершающихся нулем. Его можно смело игнорировать в простом случае
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); }
Comments