Cómo convertir bytes UTF-8 a string?

Tengo una matriz de byte[] que se carga desde un archivo que, por casualidad, sé que contiene UTF-8 . En algún código de depuración, necesito convertirlo a una cadena. ¿Hay un trazador de líneas que hará esto?

Bajo las cubiertas debería ser solo una asignación y una memcopy , por lo que incluso si no se implementa, debería ser posible.

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

Hay al menos cuatro formas diferentes de hacer esta conversión.

  1. Codificación GetString
    , pero no podrá recuperar los bytes originales si esos bytes tienen caracteres que no sean ASCII.

  2. BitConverter.ToString
    El resultado es una cadena delimitada por “-“, pero no hay un método incorporado de .NET para convertir la cadena nuevamente en matriz de bytes.

  3. Convert.ToBase64String
    Puede convertir fácilmente la cadena de salida a matriz de bytes utilizando Convert.FromBase64String .
    Nota: La cadena de salida podría contener ‘+’, ‘/’ y ‘=’. Si desea utilizar la cadena en una URL, debe codificarla explícitamente.

  4. HttpServerUtility.UrlTokenEncode
    Puede convertir fácilmente la cadena de salida en matriz de bytes utilizando HttpServerUtility.UrlTokenDecode . ¡La cadena de salida ya es amigable para las URL! La desventaja es que necesita el ensamblado System.Web si su proyecto no es un proyecto web.

Un ejemplo completo:

 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 

Una solución general para convertir de matriz de bytes a cadena cuando no se conoce la encoding:

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

Definición:

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

Utilizando:

 string result = input.ConvertByteToString(); 

La conversión de un byte[] a una string parece simple, pero cualquier tipo de encoding puede estropear la cadena de salida. Esta pequeña función solo funciona sin ningún resultado inesperado:

 private string ToString(byte[] bytes) { string response = string.Empty; foreach (byte b in bytes) response += (Char)b; return response; } 

Usar (byte)b.ToString("x2") , Salidas 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; } } 

También hay clase UnicodeEncoding, bastante simple de usar:

 ByteConverter = new UnicodeEncoding(); string stringDataForEncoding = "My Secret Data!"; byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding); Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded)); 

Alternativamente:

  var byteStr = Convert.ToBase64String(bytes); 

Un linke one-liner para convertir una matriz de bytes byteArrFilename leída de un archivo a una cadena terminada en cero de estilo ascii C puro sería esta: útil para leer cosas como tablas de índice de archivos en viejos formatos de archivo.

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

Yo uso '?' como char predeterminado para cualquier cosa que no sea pura ascii aquí, pero eso puede ser cambiado, por supuesto. Si quiere estar seguro de que puede detectarlo, simplemente use '\0' lugar, ya que TakeWhile al inicio garantiza que una cadena construida de esta manera no puede contener '\0' valores '\0' de la fuente de entrada.

BitConverter clase BitConverter se puede usar para convertir un byte[] en una string .

 var convertedString = BitConverter.ToString(byteAttay); 

La documentación de la clase BitConverter puede encontrar en MSDN

Que yo sepa, ninguna de las respuestas dadas garantiza un comportamiento correcto con terminación nula. Hasta que alguien me muestre algo diferente, escribí mi propia clase estática para manejar esto con los siguientes métodos:

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

El motivo de startIndex estaba en el ejemplo en el que estaba trabajando específicamente, necesitaba analizar un byte[] como una matriz de cadenas terminadas nulas. Se puede ignorar de forma segura en el caso simple

Prueba esto:

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

hier es un resultado donde no tienes que molestarte con la encoding. Lo usé en mi clase de red y envío objetos binarios como cadena.

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