W .NET, próbuję użyć metody Encoding.UTF8.GetString
, która pobiera tablicę bajtów i konwertuje ją na string
.Encoding.UTF8.GetString nie bierze pod uwagę Preambuły/BOM
Wygląda na to, że ta metoda ignoruje BOM (Byte Order Mark), która może być częścią prawidłowej reprezentacji binarnej ciągu UTF8 i przyjmuje go jako znak.
wiem, że mogę użyć TextReader
do strawienia LM, ile potrzeba, ale myślałem, że metoda GetString powinien być jakiś makro sprawia, że nasz kod krótszy.
Czy brakuje mi czegoś? Czy to tak celowo?
Oto kod reprodukcji:
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"));
}
widzę. Dziękuję za wyjaśnienie! –
@RonKlein Dodatkowo możesz powiedzieć 'restore2 = restore2.TrimStart ('\ uFFFF')', aby usunąć wiodące znaki BOM. Również kiedyś zastanawiałem się, dlaczego '(nowe UTF8Encoding (true)). GetBytes (" abc ")' i '(nowe UTF8Encoding (false)). GetBytes (" abc ")' produkują te same dane wyjściowe, ale jak prawdopodobnie Wiem, że 'GetBytes' nie zakłada, że jesteś na początku pliku, więc nigdy nie używa' GetPreamble'. Musisz jawnie użyć 'GetPreamble' lub pominąć jawnie preambułę, jeśli użyjesz' GetBytes' lub 'GetString'. –