如何检测字节数组中的字符串结尾到字符串转换?

我从socket接收一个字节数组中的字符串,如下所示:

[128,5,6,3,45,0,0,0,0,0] 

网络协议给出的大小是字符串的总长度(包括零),因此,在我的例子中10。

如果我只是这样做:

 String myString = new String(myBuffer); 

我在字符串5的末尾没有正确的字符。 转换似乎没有检测到字符串caracter(0)的结束。

要获得正确的大小和正确的字符串,我这样做:

 int sizeLabelTmp = 0; //Iterate over the 10 bit to get the real size of the string for(int j = 0; j<(sizeLabel); j++) { byte charac = datasRec[j]; if(charac == 0) break; sizeLabelTmp ++; } // Create a temp byte array to make a correct conversion byte[] label = new byte[sizeLabelTmp]; for(int j = 0; j<(sizeLabelTmp); j++) { label[j] = datasRec[j]; } String myString = new String(label); 

有没有更好的方法来处理这个问题?

谢谢

0不是“字符串结尾字符”。 这只是一个字节。 它是否只出现在字符串的末尾取决于您正在使用的编码(以及文本可以是什么)。 例如,如果使用UTF-16,则ASCII字符的每隔一个字节为0。

如果您确定第一个0表示字符串的结尾,您可以使用类似您给出的代码,但我会将其重写为:

 int size = 0; while (size < data.length) { if (data[size] == 0) { break; } size++; } // Specify the appropriate encoding as the last argument String myString = new String(data, 0, size, "UTF-8"); 

强烈建议您不要只使用平台默认编码 - 它不可移植,并且可能不允许所有Unicode字符。 但是,您不能随意决定 - 您需要确保生成和使用此数据的所有内容都符合编码。

如果您控制协议,那么如果您可以在字符串之前引入长度前缀,则表示编码forms中有多少字节会更好。 这样你就能够准确读取正确数量的数据(没有“过度阅读”),并且你能够判断数据是否因某种原因被截断。

可能为时已晚,但它可能对其他人有所帮助。 你可以做的最简单的事情是new String(myBuffer).trim() ,它可以为你提供你想要的东西。

您始终可以从字节数组的末尾开始,然后向后搜索,直到达到第一个非零值。 然后将其复制到一个新字节然后串起来。 希望这可以帮助:

  byte[] foo = {28,6,3,45,0,0,0,0}; int i = foo.length - 1; while (foo[i] == 0) { i--; } byte[] bar = Arrays.copyOf(foo, i+1); String myString = new String(bar, "UTF-8"); System.out.println(myString.length()); 

会给你4的结果。

Java中的字符串不以0结尾,就像在其他一些语言中一样。 0将变为所谓的空字符,允许出现在字符串中。 我建议你使用一些修剪方案,它可以检测数组的第一个索引是0并使用一个子数组来构造字符串(假设其余的后面都是0),或者只是构造字符串并调用trim() 。 这将删除前导和尾随空格,即ASCII代码为32或更低的任何字符。

如果你有必须保留的前导空格,后者将不起作用。 只要它们是空字符,使用StringBuilder并删除末尾的字符在这种情况下效果会更好。

在我看来,你忽略了read()方法返回的读取计数。 可能没有发送尾随空字节,它们可能仍然从缓冲区的初始状态遗留下来。

 int count = in.read(buffer); if (count < 0) ; // EOS: close the socket etc else String s = new String(buffer, 0, count); 

不要深入研究原始OP提到的协议考虑因素,如何修剪尾随的零?

 public static String bytesToString(byte[] data) { String dataOut = ""; for (int i = 0; i < data.length; i++) { if (data[i] != 0x00) dataOut += (char)data[i]; } return dataOut; }