10

在这个转换函数中

public 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;
}

byte[] test = GetBytes("abc");

结果数组包含零个字符

test = [97, 0, 98, 0, 99, 0]

当我们将 byte[] 转换回字符串时,结果是

string test = "a b c "

我们如何使它不会产生那些零

4

5 回答 5

6

首先让我们看看你的代码做错了什么。char在 .NET 框架中是 16 位(2 字节)。这意味着当您写入时sizeof(char),它会返回2str.Length1,所以实际上你的代码将byte[] bytes = new byte[2]是相同的byte[2]。因此,当您使用方法时,实际上是将字节从源数组Buffer.BlockCopy()复制到目标数组。2这意味着你的GetBytes()方法返回bytes[0] = 32bytes[1] = 0如果你的字符串是" ".

尝试Encoding.ASCII.GetBytes()改用。

在派生类中重写时,将指定字符串中的所有字符编码为字节序列。

const string input = "Soner Gonul";

byte[] array = Encoding.ASCII.GetBytes(input);

foreach ( byte element in array )
{
     Console.WriteLine("{0} = {1}", element, (char)element);
}

输出:

83 = S
111 = o
110 = n
101 = e
114 = r
32 =
71 = G
111 = o
110 = n
117 = u
108 = l
于 2013-01-06T12:11:17.093 回答
1

只是为了消除您对答案的困惑,C# 中的 char 类型需要 2 个字节。因此,string.toCharArray() 返回一个数组,其中每个项目占用 2 个字节的存储空间。在复制到每个项目占用 1 字节存储空间的字节数组时,会发生数据丢失。因此,结果中出现零。
如建议的那样,Encoding.ASCII.GetBytes是一个更安全的选择。

于 2013-01-06T12:22:17.343 回答
1

实际上.net(至少对于 4.0)在使用 BinaryWriter 序列化时会自动更改 char 的大小

UTF-8 字符具有可变长度(可能不是 1 个字节),ASCII 字符具有 1 个字节

'ē' = 2 个字节

'e' = 1 字节

使用时必须牢记

BinaryReader.ReadChars(stream)

如果单词 "ēvalds" = 7 字节大小将不同于 "evalds" = 6 字节

于 2013-12-02T10:08:02.803 回答
0

尝试Encoding明确指定。您可以使用下一个代码将字符串转换为具有指定编码的字节

byte[] bytes = System.Text.Encoding.ASCII.GetBytes("abc");

如果您打印字节的内容,您将得到{ 97, 98, 99 }不包含零的内容,如您的示例在您的示例默认编码中,每个符号使用 16 位。它可以通过打印结果来成为观察者

System.Text.Encoding.Unicode.GetBytes("abc"); // { 97, 0, 98, 0, 99, 0 }

然后在将其转换回来时,您应该选择适当的编码:

string str = System.Text.Encoding.ASCII.GetString(bytes);
Console.WriteLine (str);

"abc"如您预期的那样打印

于 2013-01-06T12:11:12.597 回答
0

(97,0) 是 'a' 的 Unicode 表示。Unicode 以两个字节表示每个字符。所以你不能删除零。但是您可以将编码更改为 ASCII。尝试以下将字符串转换为字节 []。

byte[] array = Encoding.ASCII.GetBytes(input);
于 2013-01-06T12:18:56.857 回答