3

虽然有 100 种方法可以解决转换问题,但我关注的是性能。

假设字符串仅包含二进制数据,就性能而言,在 C# 下将该数据转换为 byte[](不是 char[])的最快方法是什么?

澄清:这不是 ASCII 数据,而是恰好在字符串中的二进制数据。

4

4 回答 4

4

UTF8Encoding.GetBytes

于 2008-09-16T13:31:40.133 回答
3

我不确定 ASCIIEncoding.GetBytes 是否会这样做,因为它只支持范围 0x0000 到 0x007F

你告诉字符串只包含字节。但是 .NET 字符串是一个字符数组,1 个字符是 2 个字节(因为 .NET 将字符串存储为 UTF16)。因此,您可以有两种情况来存储字节 0x42 和 0x98:

  1. 该字符串是一个 ANSI 字符串并包含字节并被转换为一个 unicode 字符串,因此字节将为 0x00 0x42 0x00 0x98。(字符串存储为0x0042和0x0098)
  2. 该字符串只是一个字节数组,您将其类型转换或刚刚接收到一个字符串,因此成为以下字节 0x42 0x98。(字符串存储为 0x9842)

在第一种情况下,结果将是 0x42 和 0x3F(ascii 表示“B?”)。第二种情况会导致 0x3F(ascii 表示“?”)。这是合乎逻辑的,因为字符超出了有效的 ascii 范围,并且编码器不知道如何处理这些值。

所以我想知道为什么它是一个带字节的字符串?

  • 也许它包含一个编码为字符串的字节(例如Base64)?
  • 也许您应该从 char 数组或 byte 数组开始?

如果您确实有情况 2 并且您想从中获取字节,您应该使用UnicodeEncoding.GetBytes调用。因为这将返回 0x42 和 0x98。

如果您想从 char 数组转到 byte 数组,最快的方法是编组。但这不是很好,并且使用双内存。

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;
}
于 2008-09-16T14:20:52.057 回答
0

C#中没有ASCII 字符串这样的东西!字符串始终包含 UTF-16。没有意识到这一点会导致很多问题。也就是说,前面提到的方法有效,因为它们将字符串视为 UTF-16 编码并将字符转换为 ASCII 符号。

/编辑响应澄清:二进制数据是如何进入字符串的?字符串不应该包含二进制数据(byte[]用于此)。

于 2008-09-16T13:54:54.523 回答
0

如果要从字符串转换为二进制数据,首先必须知道使用什么编码将二进制数据转换为字符串。否则,您可能无法得到正确的二进制数据。因此,最有效的方法可能是 Encoding 子类(例如 UTF8Encoding)上的 GetBytes(),但您必须确定使用哪种编码。

Kent Boogaart 对原始问题的评论总结得很好。;]

于 2008-09-16T16:16:28.083 回答