我需要将(可能)以空结尾的 ascii 字节数组转换为 C# 中的字符串,我发现最快的方法是使用下面显示的 UnsafeAsciiBytesToString 方法。此方法使用 String.String(sbyte*) 构造函数,该构造函数在其备注中包含警告:
"假定 value 参数指向一个数组,该数组表示使用默认 ANSI 代码页(即 Encoding.Default 指定的编码方法)编码的字符串。
注意:* 因为默认的 ANSI 代码页是系统相关的,所以此构造函数从相同的有符号字节数组创建的字符串在不同的系统上可能会有所不同。* ...
* 如果指定的数组不是以 null 结尾的,则此构造函数的行为取决于系统。例如,这种情况可能会导致访问冲突。* "
现在,我很肯定字符串的编码方式永远不会改变......但我的应用程序运行的系统上的默认代码页可能会改变。那么,有什么理由我不应该为此目的使用 String.String(sbyte*) 尖叫吗?
using System;
using System.Text;
namespace FastAsciiBytesToString
{
static class StringEx
{
public static string AsciiBytesToString(this byte[] buffer, int offset, int maxLength)
{
int maxIndex = offset + maxLength;
for( int i = offset; i < maxIndex; i++ )
{
/// Skip non-nulls.
if( buffer[i] != 0 ) continue;
/// First null we find, return the string.
return Encoding.ASCII.GetString(buffer, offset, i - offset);
}
/// Terminating null not found. Convert the entire section from offset to maxLength.
return Encoding.ASCII.GetString(buffer, offset, maxLength);
}
public static string UnsafeAsciiBytesToString(this byte[] buffer, int offset)
{
string result = null;
unsafe
{
fixed( byte* pAscii = &buffer[offset] )
{
result = new String((sbyte*)pAscii);
}
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
byte[] asciiBytes = new byte[]{ 0, 0, 0, (byte)'a', (byte)'b', (byte)'c', 0, 0, 0 };
string result = asciiBytes.AsciiBytesToString(3, 6);
Console.WriteLine("AsciiBytesToString Result: \"{0}\"", result);
result = asciiBytes.UnsafeAsciiBytesToString(3);
Console.WriteLine("UnsafeAsciiBytesToString Result: \"{0}\"", result);
/// Non-null terminated test.
asciiBytes = new byte[]{ 0, 0, 0, (byte)'a', (byte)'b', (byte)'c' };
result = asciiBytes.UnsafeAsciiBytesToString(3);
Console.WriteLine("UnsafeAsciiBytesToString Result: \"{0}\"", result);
Console.ReadLine();
}
}
}