这两天开发调试一个工具时发现一个问题,往常串口波特率设置都是最大115200,这次因数据传输需要,需把串口波特率调整为2000000,于是发现了很多之前写法的一些问题。
常规做法
往常最大115200,直接从InputStream中获取数据,按照常规方式,如下:
private static byte[] readStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) > 0) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
}
但是现在因为波特率太高,于是会发现一直无法跳出while循环,当然最开始的办法也是最笨的办法,是把buffer一直增大,发现可以解决问题,但是也有其他问题,比如发送端不能持续发送,持续发送总会超过buffer大小的,并且无法及时查看到传输内容。
改进方法
考虑到InputStream源源不断的传输过来数据,那我是不是可以直接指定获取多少先拿去处理?比如正常报文长度是1024,我约定一次最多取1024*2这样,流不断掉就会一直在流里存着,一直等取完为止,只要后面的处理逻辑跟得上2000000波特率的速度,是可以维持一个平衡的。
那么如何在InputStream中获取指定长度,并且不关闭呢?
public static final int READ_BUFFER_SIZE = 1024;
/**
* 读取流中的字符到数组
* @param in 该方法执行完成不会关闭流
* @param limit 读取大小限制
* @return
* @throws IOException
*/
public static byte[] readStreamAsByteArray(InputStream in, int limit) throws IOException {
if (in == null) {
return new byte[0];
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[READ_BUFFER_SIZE];
int len;
int temp = limit - READ_BUFFER_SIZE;
while ((len = in.read(buffer)) > 0) {
output.write(buffer, 0, len);
if(output.size() > temp) {
if(output.size() == limit) {
break;
}
byte[] buffer2 = new byte[limit - output.size()];
while ((len = in.read(buffer2)) > 0) {
output.write(buffer2, 0, len);
if(output.size() == limit) {
break;
}
buffer2 = new byte[limit - output.size()];
}
break;
}
}
return output.toByteArray();
}
这样做就可以一直源源不断的从流中获取数据拿去处理了,可以实时查看处理结果,只要处理过程跟得上就可以。
当然目前测试可行,具体是否有其他问题还有待验证。
后续会就Java使用串口通信的方式再行单独整理。
评论区