C# を使用して、バイナリ データを含む文字列をバイト配列に変換する最も効率的な方法は何ですか?
質問
変換の問題を解決する方法は 100 通りありますが、私はパフォーマンスに焦点を当てています。
文字列にバイナリ データのみが含まれているとすると、C# でそのデータを byte[] (char[] ではない) に変換する、パフォーマンスの観点から最も速い方法は何ですか?
説明:これは ASCII データではなく、文字列内にたまたま存在するバイナリ データです。
解決
ASCIIEncoding.GetBytes がそれを行うかどうかはわかりません。サポートしているのは 範囲 0x0000 ~ 0x007F.
文字列にはバイトのみが含まれていると伝えます。ただし、.NET 文字列は文字の配列であり、1 文字は 2 バイトです (.NET は文字列を UTF16 として保存するため)。したがって、バイト 0x42 と 0x98 を保存するには 2 つの状況が考えられます。
- この文字列は ANSI 文字列でバイトを含んでおり、Unicode 文字列に変換されるため、バイトは 0x00 0x42 0x00 0x98 になります。(文字列は0x0042と0x0098として保存されます)
- 文字列は、文字列に型キャストまたは受信しただけのバイト配列であり、バイト 0x42 0x98 になりました。(文字列は0x9842として保存されます)
最初の状況では、結果は 0x42 および 0x3F (ASCII で「B?」) になります。2 番目の状況では、0x3F (ASCII の「?」) が返されます。文字は有効な ASCII 範囲外であり、エンコーダはそれらの値をどう処理するかわからないため、これは論理的です。
それで、なぜそれがバイトを含む文字列なのか疑問に思いますか?
- おそらく、文字列としてエンコードされたバイトが含まれている可能性があります (たとえば、 Base64)?
- おそらく、char 配列または byte 配列から始めるべきでしょうか?
本当に状況 2 があり、そこからバイトを取り出したい場合は、 UnicodeEncoding.GetBytes 電話。0x42 と 0x98 が返されるためです。
char 配列から byte 配列に変更する場合、最も速い方法はマーシャリングです。しかし、これはあまり良いことではなく、メモリを 2 倍使用することになります。
public Byte[] ConvertToBytes(Char[] source)
{
Byte[] result = new Byte[source.Length * sizeof(Char)];
IntPtr tempBuffer = Marshal.AllocHGlobal(result.Length);
try
{
Marshal.Copy(source, 0, tempBuffer, source.Length);
Marshal.Copy(tempBuffer, result, 0, result.Length);
}
finally
{
Marshal.FreeHGlobal(tempBuffer);
}
return result;
}
他のヒント
がある そんなことはない C# の ASCII 文字列として!文字列 いつも UTF-16が含まれています。これを認識しないと、多くの問題が発生します。そうは言っても、前に説明したメソッドは、文字列を UTF-16 でエンコードされたものとみなして文字を ASCII 記号に変換するため、機能します。
説明に応じて /EDIT:バイナリデータはどのようにして文字列に取り込まれたのでしょうか?文字列にはバイナリ データが含まれることは想定されていません (使用 byte[]
そのために)。
文字列からバイナリデータに変換したい場合は、 そもそもバイナリデータを文字列に変換するためにどのようなエンコーディングが使用されたかを知る必要があります. 。そうしないと、正しいバイナリ データが得られない可能性があります。したがって、おそらく最も効率的な方法は、Encoding サブクラス (UTF8Encoding など) で GetBytes() を使用することですが、どのエンコーディングであるかを確実に知っておく必要があります。
元の質問に対する Kent Boogaart のコメントは、それを非常によく要約しています。;]