Domanda

Ho un array byte [] che viene caricato da un file che mi capita di conoscere contiene UTF-8 . In alcuni codici di debug, devo convertirli in una stringa. C'è una fodera che lo farà?

Sotto le copertine dovrebbe essere solo un'allocazione e una memcopia , quindi anche se non viene implementata, dovrebbe essere possibile.

È stato utile?

Soluzione

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

Altri suggerimenti

Esistono almeno quattro modi diversi per eseguire questa conversione.

  1. GetString della codifica
    , ma non sarai in grado di recuperare i byte originali se quei byte hanno caratteri non ASCII.

  2. BitConverter.ToString
    L'output è un " - " stringa delimitata, ma non esiste un metodo incorporato .NET per riconvertire la stringa in array di byte.

  3. Convert.ToBase64String
    Puoi facilmente convertire la stringa di output in array di byte utilizzando Convert.FromBase64String .
    Nota: l'output la stringa può contenere '+', '/' e '='. Se si desidera utilizzare la stringa in un URL, è necessario codificarla esplicitamente.

  4. HttpServerUtility.UrlTokenEncode
    Puoi facilmente convertire la stringa di output in array di byte utilizzando HttpServerUtility.UrlTokenDecode . La stringa di output è già compatibile con l'URL! Il rovescio della medaglia è che ha bisogno di System.Web se il tuo progetto non è un progetto web.

Un esempio 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 soluzione generale per convertire da array di byte a stringa quando non si conosce la codifica:

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

Definizione:

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

Utilizzo:

string result = input.ConvertByteToString();

La conversione di un byte [] in una stringa sembra semplice ma è probabile che qualsiasi tipo di codifica rovini la stringa di output. Questa piccola funzione funziona senza risultati imprevisti:

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

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

    return response;
}

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

}

Esiste anche la classe UnicodeEncoding, abbastanza semplice in uso:

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

Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));

In alternativa:

 var byteStr = Convert.ToBase64String(bytes);

Un linq one-liner per la conversione di un array di byte byteArrFilename letto da un file in una pura stringa a terminazione zero in stile C ascii sarebbe questo: Comodo per leggere cose come le tabelle di indice dei file nella vecchia formati di archivio.

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

Uso '?' come carattere predefinito per tutto ciò che non è ASCII puro qui, ma che può essere modificato, ovviamente. Se vuoi essere sicuro di poterlo rilevare, usa invece '\ 0' , poiché TakeWhile all'inizio garantisce che una stringa creata in questo modo non possa contenere < code> '\ 0' dalla sorgente di input.

La classe

BitConverter può essere utilizzata per convertire un byte [] in stringa .

var convertedString = BitConverter.ToString(byteAttay);

La documentazione della classe BitConverter può essere trovata su MSDN

Per quanto ne so, nessuna delle risposte fornite garantisce un comportamento corretto con una risoluzione nulla. Fino a quando qualcuno non mi mostra diversamente ho scritto la mia classe statica per gestirla con i seguenti metodi:

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

Il motivo del startIndex era nell'esempio su cui stavo lavorando in particolare avevo bisogno di analizzare un byte [] come un array di stringhe nulle. Può essere tranquillamente ignorato nel caso semplice

hier è un risultato in cui non devi preoccuparti della codifica. L'ho usato nella mia classe di rete e ho inviato oggetti binari come stringa con esso.

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

In aggiunta alla risposta selezionata, se si utilizza .NET35 o .NET35 CE, è necessario specificare l'indice del primo byte da decodificare e il numero di byte da decodificare:

string result = System.Text.Encoding.UTF8.GetString(byteArray,0,byteArray.Length);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top