最近偶发情况虾遇到字符乱码问题如下:
最开始以为是jython的bug,后来定位发现是dboss readLine的实现上, 应该是byte处理的问题,之前的实现是:
public String readLine(int length) throws IOException {
String buf = "";
int index = 0;
while (true) {
index = buf.indexOf("\r\n");
if (index >= 0) {
break;
}
int bytesToRead = Math.min(input.available(), length);
if (bytesToRead > 0) {
byte[] data = new byte[bytesToRead];
input.read(data);
String line = new String(data, DbossClientConstant.ENCODE);
buf += line;
} else {
int b = input.read(); // 此操作会阻塞,直到有数据被读到
if (b < 0) {
throw new IOException(
" end of the socket input stream has been reached,may be server socket is closed!");
} else {
input.unread(b);
continue;
}
}
}
return buf.substring(0, index);
}
这个存在一个问题,每次从缓存区读取byte都转换成string,有可能存在读取到一一半的byte,导致乱码。修改之后的代码:
public String readLine(int length) throws IOException {
int bytesToRead = Math.min(input.available(), length);
ByteArrayOutputStream output = new ByteArrayOutputStream(bytesToRead);
int index = 0;
byte[] buffer = null;
while (true) {
buffer = output.toByteArray();
index = ToolUtil.indexOf(buffer, EOF);
if (index >= 0) {
break;
}
bytesToRead = Math.min(input.available(), length);
if (bytesToRead > 0) {
byte[] bytes = new byte[bytesToRead];
input.read(bytes);
output.write(bytes);
} else {
int b = input.read(); // 此操作会阻塞,直到有数据被读到
if (b < 0) {
throw new IOException(
" end of the socket input stream has been reached,may be server socket is closed!");
} else {
input.unread(b);
continue;
}
}
}
return new String(buffer, DbossClientConstant.ENCODE);
}
ps:还有后续问题: 记录一次bug解决过程