【问题标题】:Getting null terminated string from System.Text.Encoding.Unicode.GetString从 System.Text.Encoding.Unicode.GetString 获取空终止字符串
【发布时间】:2009-05-14 16:07:45
【问题描述】:

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

所以字节可能是:

H \0 E \0 L \0 L \0 \0 \0 \0 \0 \0 ... etc 

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

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

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

"HELLO\0\0\0\0\0\0\0\0..."

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

感谢您的任何意见。

【问题讨论】:

    标签: .net encoding bytearray getstring


    【解决方案1】:

    如果你确定其余的都是 \0,这会起作用:

    cmd = cmd.TrimEnd('\0');
    

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

    int index = cmd.IndexOf('\0');
    if (index >= 0)
       cmd = cmd.Remove(index);
    

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

    【讨论】:

      【解决方案2】:

      对于 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);
      

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

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

      【讨论】:

      • 警告:这不适用于多字节字符编码(例如您的示例中的 Unicode/UTF-16),其中 'abc' 将被编码为 {97, 0, 98, 0, 99, 0} (和一个可选的两个字节长的空终止符)。您也找不到最新的非空字节,因为前面的字符将不再正确编码(对于“a”,您将使用无效的 {97} 而不是 {97,0})
      • @Melvyn - 已修复
      【解决方案3】:

      如前所述,最简单的方法是在转换后修剪字符串。

      如果您事先知道字符数,则可以使用 GetString 重载,该重载采用起始索引和字节数,以获得正确的字符串,而无需修剪。

      如果您事先不知道字符数,并且想避免事后修剪字符串,则需要先修剪字节数组,因此您只传递您感兴趣的字节。对于 Unicode,这意味着删除包括第一对零之后的所有字节。

      【讨论】:

        【解决方案4】:

        您可以从 Stream.Read() 中获取长度。在这种情况下,流中的 \0 将不被计算在内,您将获得 5 的长度。然后您可以使用 Encoding.UTF8.GetString 按长度修剪字符串。

        int length = peerStream.Read(buffer, 0, buffer.Length);
        receive = Encoding.UTF8.GetString(buffer, 0, length);
        

        【讨论】:

        • 我相信 Class Skeleton 的回答也涵盖了您的建议。您或许可以更好地解释您的代码。
        猜你喜欢
        • 2011-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-03
        • 2012-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多