In .NET versuche ich Encoding.UTF8.GetString
Methode, die ein Byte-Array verwendet und konvertiert es in eine string
.Encoding.UTF8.GetString berücksichtigt nicht die Präambel/BOM
Es sieht so aus, als ob diese Methode die BOM (Byte Order Mark) ignoriert, die Teil einer legitimen Binärdarstellung einer UTF8-Zeichenfolge sein könnte, und sie als Zeichen interpretiert.
Ich weiß, dass ich eine TextReader
verwenden kann, um die Stückliste nach Bedarf zu verdauen, aber ich dachte, dass die GetString-Methode eine Art Makro sein sollte, das unseren Code kürzer macht.
Fehle ich etwas? Ist das so absichtlich?
Hier ist eine Reproduktion Code:
static void Main(string[] args)
{
string s1 = "abc";
byte[] abcWithBom;
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(ms, new UTF8Encoding(true)))
{
sw.Write(s1);
sw.Flush();
abcWithBom = ms.ToArray();
Console.WriteLine(FormatArray(abcWithBom)); // ef, bb, bf, 61, 62, 63
}
byte[] abcWithoutBom;
using (var ms = new MemoryStream())
using (var sw = new StreamWriter(ms, new UTF8Encoding(false)))
{
sw.Write(s1);
sw.Flush();
abcWithoutBom = ms.ToArray();
Console.WriteLine(FormatArray(abcWithoutBom)); // 61, 62, 63
}
var restore1 = Encoding.UTF8.GetString(abcWithoutBom);
Console.WriteLine(restore1.Length); // 3
Console.WriteLine(restore1); // abc
var restore2 = Encoding.UTF8.GetString(abcWithBom);
Console.WriteLine(restore2.Length); // 4 (!)
Console.WriteLine(restore2); // ?abc
}
private static string FormatArray(byte[] bytes1)
{
return string.Join(", ", from b in bytes1 select b.ToString("x"));
}
ich sehe. Danke für die Klarstellung! –
@RonKlein Zusätzlich können Sie 'restore2 = restore2.TrimStart ('\ uFEFF')' sagen, um führende BOM-Zeichen zu entfernen. Ich habe auch einmal gefragt, warum '(neue UTF8Encoding (true)). GetBytes (" abc ")' und '(neue UTF8Encoding (false)). GetBytes (" abc ")' produzieren die gleiche Ausgabe, aber wie Sie wahrscheinlich "GetBytes" geht nicht davon aus, dass Sie sich am Anfang einer Datei befinden. Daher wird nie "GetPreamble" verwendet. Sie müssen 'GetPreamble' explizit angeben oder die Präambel explizit überspringen, wenn Sie' GetBytes' oder 'GetString' verwenden. –