在C#语言中将字符串转换为字节数组

Converting string to byte array in C#

我对C很陌生。我正在把一些东西从vb转换成c。此语句的语法有问题:

1
2
3
4
if ((searchResult.Properties["user"].Count > 0))
{
    profile.User = System.Text.Encoding.UTF8.GetString(searchResult.Properties["user"][0]);
}

然后我看到以下错误:

Argument 1: cannot convert from 'object' to 'byte[]'

The best overloaded method match for
'System.Text.Encoding.GetString(byte[])' has some invalid arguments

我试着根据这篇文章修改代码,但还是没有成功。

1
string User = Encoding.UTF8.GetString("user", 0);

有什么建议吗?


如果您已经有了一个字节数组,那么您将需要知道使用了什么类型的编码来将其转换成该字节数组。

例如,如果字节数组是这样创建的:

1
byte[] bytes = Encoding.ASCII.GetBytes(someString);

您需要将其转换回这样的字符串:

1
string someString = Encoding.ASCII.GetString(bytes);

如果您可以在继承的代码中找到用于创建字节数组的编码,那么应该设置该编码。


首先,添加System.Text名称空间

1
using System.Text;

然后使用这个代码

1
2
string input ="some text";
byte[] array = Encoding.ASCII.GetBytes(input);

希望修复它!


还可以使用扩展方法向string类型添加方法,如下所示:

1
2
3
4
5
6
7
static class Helper
{
   public static byte[] ToByteArray(this string str)
   {
      return System.Text.Encoding.ASCII.GetBytes(str);
   }
}

使用方法如下:

1
2
string foo ="bla bla";
byte[] result = foo.ToByteArray();


1
2
3
4
5
6
7
8
9
10
11
12
13
static byte[] GetBytes(string str)
{
     byte[] bytes = new byte[str.Length * sizeof(char)];
     System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
     return bytes;
}

static string GetString(byte[] bytes)
{
     char[] chars = new char[bytes.Length / sizeof(char)];
     System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
     return new string(chars);
}


1
var result = System.Text.Encoding.Unicode.GetBytes(text);


用这个

1
byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);


以下方法仅在字符为1字节时有效。(默认的Unicode将不起作用,因为它是2个字节)

1
2
3
4
5
6
7
8
9
10
11
12
public static byte[] ToByteArray(string value)
{            
    char[] charArr = value.ToCharArray();
    byte[] bytes = new byte[charArr.Length];
    for (int i = 0; i < charArr.Length; i++)
    {
        byte current = Convert.ToByte(charArr[i]);
        bytes[i] = current;
    }

    return bytes;
}

保持简单


对Justinstolle编辑的改进(Eran Yogev使用Blockcopy)。

提出的解决方案确实比使用编码更快。问题是它不适用于长度不均匀的字节数组的编码。如前所述,它引发了一个超出限制的异常。从字符串解码时,将长度增加1会留下一个尾随字节。

对我来说,当我想从DataTableJSON进行编码时,需求就出现了。我在寻找一种将二进制字段编码为字符串并从字符串解码回byte[]的方法。

因此,我创建了两个类——一个类包装上述解决方案(当从字符串编码时很好,因为长度总是相等的),另一个类处理byte[]编码。

我通过添加一个字符来解决长度不均匀的问题,该字符告诉我二进制数组的原始长度是奇数("1")还是偶数("0")。

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public static class StringEncoder
{
    static byte[] EncodeToBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
    static string DecodeToString(byte[] bytes)
    {
        char[] chars = new char[bytes.Length / sizeof(char)];
        System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
}

public static class BytesEncoder
{
    public static string EncodeToString(byte[] bytes)
    {
        bool even = (bytes.Length % 2 == 0);
        char[] chars = new char[1 + bytes.Length / sizeof(char) + (even ? 0 : 1)];
        chars[0] = (even ? '0' : '1');
        System.Buffer.BlockCopy(bytes, 0, chars, 2, bytes.Length);

        return new string(chars);
    }
    public static byte[] DecodeToBytes(string str)
    {
        bool even = str[0] == '0';
        byte[] bytes = new byte[(str.Length - 1) * sizeof(char) + (even ? 0 : -1)];
        char[] chars = str.ToCharArray();
        System.Buffer.BlockCopy(chars, 2, bytes, 0, bytes.Length);

        return bytes;
    }
}

如果'searchresult.properties["user"[0]'的结果是字符串:

1
2
3
4
5
if ( ( searchResult.Properties ["user" ].Count > 0 ) ) {

   profile.User = System.Text.Encoding.UTF8.GetString ( searchResult.Properties ["user" ] [ 0 ].ToCharArray ().Select ( character => ( byte ) character ).ToArray () );

}

关键是,可以使用linq将字符串转换为byte[]:

1
.ToCharArray ().Select ( character => ( byte ) character ).ToArray () )

反过来说:

1
.Select ( character => ( char ) character ).ToArray () )

有人知道为什么不这么做的原因吗?

1
mystring.Select(Convert.ToByte).ToArray()


这个问题已经被回答了很多次,但是随着C 7.2和跨度类型的引入,在不安全的代码中有一种更快的方法可以做到这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static class StringSupport
{
    private static readonly int _charSize = sizeof(char);

    public static unsafe byte[] GetBytes(string str)
    {
        if (str == null) throw new ArgumentNullException(nameof(str));
        if (str.Length == 0) return new byte[0];

        fixed (char* p = str)
        {
            return new Span<byte>(p, str.Length * _charSize).ToArray();
        }
    }

    public static unsafe string GetString(byte[] bytes)
    {
        if (bytes == null) throw new ArgumentNullException(nameof(bytes));
        if (bytes.Length % _charSize != 0) throw new ArgumentException($"Invalid {nameof(bytes)} length");
        if (bytes.Length == 0) return string.Empty;

        fixed (byte* p = bytes)
        {
            return new string(new Span<char>(p, bytes.Length / _charSize));
        }
    }
}

请记住,字节代表一个UTF-16编码的字符串(在C_land中称为"Unicode")。

一些快速基准测试表明,上述方法比它们的编码快大约5倍。中型字符串(30-50个字符)的unicode.getbytes(…)/getstring(…)实现,而大型字符串则更快。这些方法似乎也比使用带有marshal.copy(..)或buffer.memorycopy(…)的指针更快。


这对我很有用,之后我可以转换,把我的图片放在数据库的字节字段中。

1
2
3
4
using (MemoryStream s = new MemoryStream(DirEntry.Properties["thumbnailphoto"].Value as byte[]))
{
    return s.ToArray();
}