RXTX java,inputStream不会返回所有缓冲区

RXTX java,inputStream不会返回所有缓冲区,java,serial-port,rxtx,Java,Serial Port,Rxtx,这是我的代码,我正在使用 代码的其余部分与相同,我只是更改了两件事 InputStream in = serialPort.getInputStream(); OutputStream out = serialPort.getOutputStream(); 它们现在是全局变量,而且 (new Thread(new SerialReader(in))).start(); (new Thread(new SerialWriter(out))).start(); 现在不存在 我(每秒)发送这个 这

这是我的代码,我正在使用

代码的其余部分与相同,我只是更改了两件事

InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
它们现在是全局变量,而且

(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
现在不存在

我(每秒)发送这个

这就是我得到的:

123456789123
456789
123456789
1234567891
23456789
有人能帮我吗

编辑

后来,我找到了更好的解决方法。谢谢,这是阅读代码

public byte[] Read(int intEspera) throws IOException {

        try {
            Thread.sleep(intEspera);
        } catch (InterruptedException ex) {
            Logger.getLogger(COM_ClComunica.class.getName()).log(Level.SEVERE, null, ex);
        }//*/

        byte[] buffer = new byte[528];

        int len = 0;


        while (in.available() > 0) {
            len = in.available();
            in.read(buffer,0,528);
        }

        return buffer;
    }

对我来说,消除睡眠是不可能的,但这并不是一个问题,所以,谢谢你,你应该注意,它的定义如下

返回可从此输入流读取(或跳过)的字节数的估计值,而无需在下次调用此输入流的方法时阻塞。下一次调用可能是同一个线程或另一个线程。单个读取或跳过这么多字节不会阻塞,但可能读取或跳过更少的字节

正如你所看到的,这不是你所期望的。相反,您希望检查流的结束,这通过返回
-1
来指示

此外,由于您不记得在读取循环的前一次迭代中已经读取了多少数据,因此可能会覆盖缓冲区中的前一次数据,这也不是您想要的

您似乎想要的是以下内容:

private static final int MESSAGE_SIZE = 20;

public byte[] read() throws IOException {
  final byte[] buffer = new byte[MESSAGE_SIZE];
  int total = 0;
  int read = 0;
  while (total < MESSAGE_SIZE
            && (read = in.read(buffer, total, MESSAGE_SIZE - total)) >= 0) {
    total += read;
  }
  return buffer;
}
private static final int MESSAGE_SIZE=20;
公共字节[]读取()引发IOException{
最终字节[]缓冲区=新字节[消息大小];
int-total=0;
int read=0;
while(总<消息大小
&&(read=in.read(缓冲区、总计、消息大小-总计))>=0){
总计+=读取;
}
返回缓冲区;
}
这将迫使它读取最多20个字节的,在到达流末尾的情况下读取更少的字节


特别感谢EJP提醒我保持帖子的质量并确保它们是正确的。

摆脱
可用()
测试。它所做的只是告诉您是否有数据可以在不阻塞的情况下读取。这与告诉你整个消息的结尾不同。
available(),
几乎没有正确的用法,这不是其中之一


并在读取时前进缓冲区指针。您需要跟踪到目前为止已读取的字节数,并将其用作read()的第二个参数,将buffer.length用作第三个参数。

分段由实现决定。如果你关心一次接收完整的消息,考虑使用一个包含消息大小的消息头。但是,我有这个大小,在这个时刻是20,我把所有的缓冲区发送到读取(1024)。我试图打印所有的缓冲区,它是一样的,只是有很多空间,因为它的大小…没有多大的意义尝试,因为它将继续覆盖以前读取的数据,它肯定不会停止在20字节的方式,你写它。Downvote.正确的覆盖以前读取的数据,这是一个愚蠢的错误代表我。。。但是现在它应该被绑定到20字节。谢谢你指出错误,不过。。。有时我没有集中精力:基于GunBlade的信息,我认为您的解释是正确的,而且实现看起来很好。就我个人而言,我更喜欢在我自己的读取实现中包含一个超时,因为InputStream.read()将无限期地阻塞…好吧,这是解决我的问题的更好的方法,不完全像这样,但我使用了你的想法,是的,我在30毫秒内得到了我所需要的一切。谢谢。
public byte[] Read(int intEspera) throws IOException {

        try {
            Thread.sleep(intEspera);
        } catch (InterruptedException ex) {
            Logger.getLogger(COM_ClComunica.class.getName()).log(Level.SEVERE, null, ex);
        }//*/

        byte[] buffer = new byte[528];

        int len = 0;


        while (in.available() > 0) {
            len = in.available();
            in.read(buffer,0,528);
        }

        return buffer;
    }
private static final int MESSAGE_SIZE = 20;

public byte[] read() throws IOException {
  final byte[] buffer = new byte[MESSAGE_SIZE];
  int total = 0;
  int read = 0;
  while (total < MESSAGE_SIZE
            && (read = in.read(buffer, total, MESSAGE_SIZE - total)) >= 0) {
    total += read;
  }
  return buffer;
}