-
场景描述:
在spring boot中使用sokect 接受来自PHP服务器的执行结果。发送请求后得到的内容中含有乱码,确认了所有编码格式均为UTF-8,并且php端调用的接口所使用的方法执行后返回的是正常的结果。因此怀疑是否是因为Spring boot Socket问题导致,再搜索文章并且调试之后,发现并非此原因。 网上推荐使用BufferReader读取 但是内置方法不包含按byte[]读取,因此放弃。 还有一种解释是说UTF-8中文为3个字节,符号数字为单字节,如果以1024长度的字节数组截取有可能第1023为中文的半个字符,而下一个字符到了下一组中。而此时因为已经使用toString获取了字符串,就导致了最后一个字符为乱码。 -
解决方案:
使用ByteBuffer先预存所有的byte[],在读取完所有数据之后,再进行String的转换。 -
代码:
String reqStr="请求内容";
ByteBuffer buf = ByteBuffer.allocate(4 + reqStr.getBytes().length);
buf.putInt(reqStr.getBytes().length);
buf.put(reqStr.getBytes());
//socket连接设置 1.7语法糖
Socket socket=new Socket(jobTagSocketHost,config.getApiSocketPort());)
{
//调用内部socket接口
socket.getOutputStream().write(buf.array());//发送请求字符串
//读取数据长度
byte[] size = new byte[4];
socket.getInputStream().read(size);
int size_t = Bytes.toInt(size, 0, 4);
//读取数据,每次读取1024字节,防止数据丢失,或读不全
byte[] data = new byte[1024];
//如果不使用bytebuffer 会导致循环时转换的最后一个字节有可能是中文的半个字节
ByteBuffer bb= ByteBuffer.allocate(size_t);
while (size_t > 0) {
int dataSize = socket.getInputStream().read(data);
bb.put(Arrays.copyOfRange(data, 0, dataSize));
size_t -= dataSize;
}
//最终-查询结果字符串
String finalStr = new String(bb.array());
-
问题:
有可能会有大量数据情况 会导致OOM发生,预申请的空间可能过大,需要在申请前进行判断,如果超过某个大小则抛出异常。比如 size为2048000000 ,2G 则必然会在小jvm设置下发生 java heap out of memory 问题。
版权声明:本文为qq_39259062原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。