(おそらく) null で終了する ascii バイトの配列を C# の文字列に変換する必要があります。これを行うために見つけた最速の方法は、以下に示す UnsafeAsciiBytesToString メソッドを使用することです。このメソッドは、注釈に警告を含む String.String(sbyte*) コンストラクターを使用します。
「値パラメーターは、既定の 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();
}
}
}