Трябва да преобразувам (евентуално) нулев прекратен масив от ascii байтове в низ в C# и най-бързият начин, който открих, е да използвам моя метод UnsafeAsciiBytesToString, показан по-долу. Този метод използва конструктора String.String(sbyte*), който съдържа предупреждение в забележките си:
„Предполага се, че параметърът стойност сочи към масив, представляващ низ, кодиран с помощта на ANSI кодовата страница по подразбиране (т.е. методът на кодиране, определен от Encoding.Default).
Забележка: * Тъй като кодовата страница на ANSI по подразбиране зависи от системата, низът, създаден от този конструктор от масиви от идентични байтове със знак, може да се различава в различните системи. * ...
* Ако указаният масив не е с нула, поведението на този конструктор зависи от системата. Например, такава ситуация може да причини нарушение на достъпа. * "
Сигурен съм, че начинът, по който низът е кодиран, никога няма да се промени... но кодовата страница по подразбиране в системата, на която работи приложението ми, може да се промени. И така, има ли някаква причина да не крещя от използването на 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();
}
}
}