从System.Text.Encoding.Unicode.GetString获取以null结尾的字符串

Dou*_*ugN 10 .net encoding bytearray getstring

我有一个从外部实体收到的字节数组.它是固定的大小.这些字节包含一个unicode字符串,其中0个值用于填充缓冲区的其余部分:

所以字节可能是:

H \0 E \0 L \0 L \0 \0 \0 \0 \0 \0 ... etc 
Run Code Online (Sandbox Code Playgroud)

我正在获取缓冲区并将其转换为字符串,如下所示:

byte[] buffer = new byte[buffSize];
m_dataStream.Read(buffer, 0, buffSize);
String cmd = System.Text.Encoding.Unicode.GetString(buffer);
Run Code Online (Sandbox Code Playgroud)

我得到的是一个看起来像这样的字符串:

"HELLO\0\0\0\0\0\0\0\0..."
Run Code Online (Sandbox Code Playgroud)

我如何告诉GetString在第一个Unicode null处终止字符串(即我只是回到"HELLO")?

感谢您的任何意见.

Meh*_*ari 13

如果你确定其余的都是\ 0,这将有效:

cmd = cmd.TrimEnd('\0');
Run Code Online (Sandbox Code Playgroud)

否则,如果您只想在第一个null之前获取所有内容:

int index = cmd.IndexOf('\0');
if (index >= 0)
   cmd = cmd.Remove(index);
Run Code Online (Sandbox Code Playgroud)

请注意,Unicode.GetString将处理双\ 0.你应该只找一个\ 0.


Cla*_*ton 5

对于 UTF8/ASCII 编码,您可以通过查找缓冲区中第一次出现的空终止符(使用System.Array.IndexOf)来实现此目的,而无需重新处理字符串。然后,您可以使用重载System.Text.Encoding.Unicode.GetString方法创建一个达到给定缓冲区大小的字符串。

下面的示例也适用于不包含空字节的缓冲区:

byte[] buffer = new byte[buffSize];
m_dataStream.Read(buffer, 0, buffSize);
var size = System.Array.IndexOf(buffer, (byte)0);
String cmd = System.Text.Encoding.Unicode.GetString(buffer, 0, size < 0 ? buffSize : size);
Run Code Online (Sandbox Code Playgroud)

对于 UTF16,您可以使用类似的 for 循环方法(查找第一对空字符...例如if (buffer[i] == (byte)0 && buffer[i] == buffer[i+1]).

如果不关心创建临时字符串,那么接受的答案是最好的解决方案。

  • 警告:这不适用于多字节字符编码(例如示例中的 Unicode/UTF-16),其中“abc”将被编码为 {97, 0, 98, 0, 99, 0} (以及可选的两个字节长的 null -终结者)。您也无法找到最新的非空字节,因为前面的字符将不再被正确编码(对于“a”,您将得到无效的 {97} 而不是 {97,0}) (2认同)