我从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 :(得分:11)
可能为时已晚,但它可能对其他人有所帮助。您可以做的最简单的事情是new String(myBuffer).trim()
,它可以为您提供您想要的内容。
答案 1 :(得分:7)
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字符。但是,您不能随意决定 - 您需要确保生成和使用此数据的所有内容都符合编码。
如果您控制协议,如果您可以在字符串之前引入长度前缀,那么它将更好 ,以指示编码形式中有多少字节。通过这种方式,您可以准确读取正确数量的数据(没有“过度读取”),并且您可以判断数据是否因某种原因被截断。
答案 2 :(得分:2)
Java中的字符串不会以0结尾,就像在其他一些语言中一样。 0将变为所谓的空字符,允许出现在字符串中。我建议你使用一些修剪方案,要么检测数组的第一个索引是0,并使用子数组来构造字符串(假设其余的后面都是0),或者只是构造字符串并调用{{ 1}}。这将删除前导和尾随空格,即ASCII代码为32或更低的任何字符。
如果您必须保留前导空格,后者将无效。只要它们是空字符,使用StringBuilder并在最后删除字符在这种情况下会更好。
答案 3 :(得分:2)
您始终可以从字节数组的末尾开始,然后向后搜索,直到达到第一个非零值。然后将其复制到一个新字节然后串起来。希望这会有所帮助:
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的结果。
答案 4 :(得分:1)
在我看来,您忽略了read()方法返回的读取计数。可能没有发送尾随空字节,它们可能仍然从缓冲区的初始状态中遗留下来。
int count = in.read(buffer);
if (count < 0)
; // EOS: close the socket etc
else
String s = new String(buffer, 0, count);
答案 5 :(得分:1)
不要深入研究原始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;
}