Pregunta

Tengo una matriz byte [] que se carga desde un archivo que conozco contiene UTF-8 . En algún código de depuración, necesito convertirlo en una cadena. ¿Hay un trazador de líneas que haga esto?

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

¿Fue útil?

Solución

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

Otros consejos

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

  1. GetString
    Encoding, pero no podrá recuperar los bytes originales si esos bytes no tienen caracteres ASCII.

  2. BitConverter.ToString
    El resultado es un " - " cadena delimitada, pero no hay un método incorporado .NET para convertir la cadena de nuevo a matriz de bytes.

  3. Convert.ToBase64String
    Puede convertir fácilmente la cadena de salida de nuevo a la matriz de bytes utilizando Convert.FromBase64String .
    Nota: La salida la cadena 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 de nuevo a matriz de bytes utilizando HttpServerUtility.UrlTokenDecode . La cadena de salida ya es compatible con URL! La desventaja es que necesita el ensamblaje 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 una matriz de bytes a una cadena cuando no conoce la codificación:

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

Uso :

string result = input.ConvertByteToString();

Convertir un byte [] en una cadena parece simple, pero es probable que cualquier tipo de codificación estropee la cadena de salida. Esta pequeña función funciona sin resultados inesperados:

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

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

    return response;
}

Usando (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 existe la 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 linq de una sola línea para convertir una matriz de bytes byteArrFilename leída de un archivo a una cadena ASCII estilo C terminada en cero sería lo siguiente: Práctico para leer cosas como tablas de índice de archivos en la antigüedad formatos de archivo.

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

Uso '?' como carácter predeterminado para cualquier cosa que no sea puramente ascii aquí, pero eso puede cambiarse, por supuesto. Si quiere asegurarse de poder detectarlo, simplemente use '\ 0' , ya que el TakeWhile al inicio asegura que una cadena construida de esta manera no puede contener < código> '\ 0' valores de la fuente de entrada.

La clase

BitConverter se puede utilizar para convertir un byte [] en string .

var convertedString = BitConverter.ToString(byteAttay);

La documentación de la clase BitConverter se 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 lo contrario, 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);
}

La razón del startIndex estaba en el ejemplo en el que estaba trabajando específicamente, necesitaba analizar un byte [] como una matriz de cadenas terminadas en nulo. Se puede ignorar de forma segura en el caso simple

hier es un resultado en el que no tuvo que molestarse con la codificación. Lo usé en mi clase de red y envié objetos binarios como una cadena con él.

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

Además de la respuesta seleccionada, si está utilizando .NET35 o .NET35 CE, debe especificar el índice del primer byte a decodificar y el número de bytes a decodificar:

string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top