使用 C#,将包含二进制数据的字符串转换为字节数组的最有效方法是啥

Posted

技术标签:

【中文标题】使用 C#,将包含二进制数据的字符串转换为字节数组的最有效方法是啥【英文标题】:Using C#, what is the most efficient method of converting a string containing binary data to an array of bytes使用 C#,将包含二进制数据的字符串转换为字节数组的最有效方法是什么 【发布时间】:2010-09-09 11:41:45 【问题描述】:

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

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

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

【问题讨论】:

字符串只包含二进制数据?这是什么意思?它只有'1'和'0'字符吗? 【参考方案1】:

UTF8Encoding.GetBytes

【讨论】:

【参考方案2】:

我不确定 ASCIIEncoding.GetBytes 是否会这样做,因为它只支持range 0x0000 to 0x007F。

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

    该字符串是 ANSI 字符串,包含字节,并被转换为 unicode 字符串,因此字节将为 0x00 0x42 0x00 0x98。 (字符串存储为0x0042和0x0098) 字符串只是一个字节数组,您输入或刚刚接收到一个字符串,因此成为以下字节 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;

【讨论】:

@Davy Landman:我认为我们都可以使用更多关于他的要求的细节 @sixlettervariables:确实,我只是想向 Noah 解释一下,他的说明不够清楚。【参考方案3】:

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

/EDIT 回应澄清:二进制数据是如何进入字符串的?字符串不应该包含二进制数据(使用byte[])。

【讨论】:

我认为用户的文件格式很奇怪,混合了文本和二进制数据。【参考方案4】:

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

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

【讨论】:

以上是关于使用 C#,将包含二进制数据的字符串转换为字节数组的最有效方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

将字节数组转换为字符串在c#中不起作用

将包含十六进制值的字节数组转换为十进制值

如何将十六进制字符串转换为字节数组? [复制]

十六进制字符串到字节数组 C# [重复]

从字节数组转换为字符串十六进制c# [重复]

在 C# 中有效地将字符串转换为字节数组(不使用编码)[重复]