侧边栏壁纸
博主头像
沙漠渔

把過去的累積,善用到當下

  • 累计撰写 490 篇文章
  • 累计创建 295 个标签
  • 累计收到 960 条评论
标签搜索

目 录CONTENT

文章目录

大数据传输情况下,如何更好的获取InputStream中获取数据?

沙漠渔
2022-08-11 / 0 评论 / 0 点赞 / 1,160 阅读 / 2,151 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-08-11,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

这两天开发调试一个工具时发现一个问题,往常串口波特率设置都是最大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使用串口通信的方式再行单独整理。

0
广告 广告

评论区