我有一个字节数组作为输入。这应该是符合标准的UTF8 HTML的二进制表示。它是,但大部分时间只是。有时它还包含嵌入的空值(\x0
字符或NUL
)。这不在我的控制之下。我需要将这个字节数组转换为字符串。
到目前为止尝试过:
StreamReader
或TextReader
不起作用,因为它在点击第一个NUL
时停止Encoding.UTF8.GetString
也不起作用 - 也停在第一个NUL
什么有效,但相当不优雅:
mynewarray = myoldarray.Where( x => x!=0).ToArray();
var output = Encoding.UTF8.GetString(mynewarray);
除了创建一个跳过NUL
字符然后使用上述解决方案之一的新字节数组外,还有更优雅的方法吗?字节数组可能非常大,超过2-4 Mb ...... MSDN告诉Strings实际上可能包含嵌入式NUL
,但没有说明处理此类字符串的最佳方法是什么。
答案 0 :(得分:1)
你的字符串已经是正确的了。它将包含NUL
个字符。但是当你使用包含NUL
字符的字符串时,你会遇到各种各样的问题。
Encoding.UTF8.GetString
不会停留在\ 0,正如您在我的示例中看到的那样。
看看输出这样一个字符串时会发生什么:
var text = new byte[]{65, 65, 0, 65};
var s = Encoding.UTF8.GetString(text);
Console.WriteLine("len is: " + s.Length + " chars");
Console.WriteLine("text: '" + s + "'");
Console.WriteLine("this line doesn't appear because NUL was sent to console");
输出是:
len is: 4 chars
text: 'AA
答案 1 :(得分:0)
使用GetString的重载,它接受一个起始索引和要解码的字节数
var output = Encodeing.UTF8.GetString(mynewarray, 0, mynewarray.Length);
答案 2 :(得分:0)
您的代码对我来说很好,但您可以通过手动控制缓冲区大小(不确定Where()
做什么)和/或使用不安全的代码来优化它。
指针数学非常适合快速迭代数组,并且您可以完全控制您希望推进内存指针的程度(因此它“不安全”)。这意味着您可以随意使用/跳过任何字符。为此,我在c#中定期使用优化缓冲区+不安全代码。
.NET框架在适当的地方使用缓冲和不安全的代码,但由于您知道自己的确切要求,因此可以调整性能。但是,它会导致更详细的代码。