Comment convertir UTF-8 byte [] en chaîne de caractères?
j'ai un tableau byte[]
qui est chargé à partir d'un fichier que je connais contient UTF-8 . Dans un code de débogage, je dois le convertir en chaîne. Y a-t-il un seul paquebot qui fera cela?
sous les couvertures, il devrait être juste une allocation et une memcopy , donc même si elle n'est pas mise en œuvre, il devrait être possible.
13 réponses
string result = System.Text.Encoding.UTF8.GetString(byteArray);
il y a au moins quatre façons différentes de faire cette conversion.
-
GetString de Encoding
, mais vous ne pourrez pas récupérer les octets originaux si ces octets ont des caractères non-ASCII. -
BitConverter.ToString
la sortie est un " - " chaîne délimitée, mais il n'y a pas de .net intégré méthode pour convertir la chaîne vers le tableau d'octets. -
Convertir.ToBase64String
vous pouvez facilement convertir la chaîne de sortie en tableau de octets en utilisantConvert.FromBase64String
.
Note: la chaîne de sortie peut contenir '+', '/' et '='. Si vous voulez utiliser la chaîne dans une URL, vous devez l'encoder explicitement. -
HttpServerUtility.UrlTokenEncode
vous pouvez facilement convertir la chaîne de sortie en un tableau de octets en utilisantHttpServerUtility.UrlTokenDecode
. La chaîne de sortie est déjà conviviale! L'inconvénient est qu'il a besoinSystem.Web
d'assemblage si votre projet n'est pas un projet web.
un exemple complet:
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
une solution générale pour passer d'un tableau d'octets à une chaîne de caractères lorsque vous ne connaissez pas l'encodage:
static string BytesToStringConverted(byte[] bytes)
{
using (var stream = new MemoryStream(bytes))
{
using (var streamReader = new StreamReader(stream))
{
return streamReader.ReadToEnd();
}
}
}
définition:
public static string ConvertByteToString(this byte[] source)
{
return source != null ? System.Text.Encoding.UTF8.GetString(source) : null;
}
utilisant:
string result = input.ConvertByteToString();
convertir un byte[]
en un string
semble simple mais tout type d'encodage est susceptible de gâcher la chaîne de sortie. Cette petite fonction fonctionne sans aucun résultat inattendu:
private string ToString(byte[] bytes)
{
string response = string.Empty;
foreach (byte b in bytes)
response += (Char)b;
return response;
}
Utilisant (byte)b.ToString("x2")
, Sorties 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;
}
}
il y a aussi la classe UnicodeEncoding, assez simple d'utilisation:
ByteConverter = new UnicodeEncoding();
string stringDataForEncoding = "My Secret Data!";
byte[] dataEncoded = ByteConverter.GetBytes(stringDataForEncoding);
Console.WriteLine("Data after decoding: {0}", ByteConverter.GetString(dataEncoded));
un Linq one-liner pour convertir un tableau d'octets byteArrFilename
lu à partir d'un fichier en une chaîne de caractères pur ascii c-style zero-terminated serait ceci: pratique pour lire des choses comme les tables d'index de fichiers dans les anciens formats d'archives.
String filename = new String(byteArrFilename.TakeWhile(x => x != 0)
.Select(x => x < 128 ? (Char)x : '?').ToArray());
j'utilise '?'
en tant que par défaut char pour ce qui n'est pas pur ascii ici, mais qui peut être changé, bien sûr. Si vous voulez être sûr que vous pouvez le détecter, il suffit d'utiliser '"151930920"'
à la place, puisque le TakeWhile
au début assure qu'un la chaîne construite de cette façon ne peut pas contenir les valeurs '"151930920"'
de la source d'entrée.
à ma connaissance, aucune des réponses données ne garantit un comportement correct avec une terminaison nulle. Jusqu'à ce que quelqu'un me montre différemment j'ai écrit ma propre classe statique pour gérer cela avec les méthodes suivantes:
// Mimics the functionality of strlen() in c/c++
// Needed because niether StringBuilder or Encoding.*.GetString() handle "151900920" 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 raison pour le startIndex
était dans l'exemple sur lequel je travaillais spécifiquement je devais analyser un byte[]
comme un tableau de chaînes à terminaison nulle. Il peut être ignoré dans le cas simple
essayez ceci:
string myresult = System.Text.Encoding.UTF8.GetString(byteArray);
hier est un résultat où vous n'avez pas eu à vous soucier de l'encodage. Je l'ai utilisé dans ma classe de réseau et j'ai envoyé des objets binaires avec.
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);
}