Come convertire UTF-8 byte [] in stringa?
-
05-07-2019 - |
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.
Soluzione
string result = System.Text.Encoding.UTF8.GetString(byteArray);
Altri suggerimenti
Esistono almeno quattro modi diversi per eseguire questa conversione.
GetString della codifica
, ma non sarai in grado di recuperare i byte originali se quei byte hanno caratteri non ASCII.BitConverter.ToString
L'output è un " - " stringa delimitata, ma non esiste un metodo incorporato .NET per riconvertire la stringa in array di byte.Convert.ToBase64String
Puoi facilmente convertire la stringa di output in array di byte utilizzandoConvert.FromBase64String
.
Nota: l'output la stringa può contenere '+', '/' e '='. Se si desidera utilizzare la stringa in un URL, è necessario codificarla esplicitamente.HttpServerUtility.UrlTokenEncode
Puoi facilmente convertire la stringa di output in array di byte utilizzandoHttpServerUtility.UrlTokenDecode
. La stringa di output è già compatibile con l'URL! Il rovescio della medaglia è che ha bisogno diSystem.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.
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);