开发者社区> 问答> 正文

java怎么一次性读取串口内所有的数据:报错

我写了一个类读取串口的数据,我打印的时候数据分成了好几段,怎么一次性读取串口内所有的数据?

展开
收起
kun坤 2020-06-07 22:36:25 657 0
1 条回答
写回答
取消 提交回答
  • 什么意思?不能循环读取数据,存起来,然后再打印?还是因为你没办法判断数据什么时候结束?
    ######就是我手上有一个终端,向连在COM1上的接收器发送数据,发送完一条数据后控制台上马上现实这条数据,我想实现的效果是一行显示一条数据,现在的情况是一条数据分成了几行显示!我如果用循环的方式一个一个的读字节,就会把以前输入的数据也打印出来,我只想打印当前这条数据,一行一条数据。######串口性能有限,不同的串口设备之间都有不同,只能是被动的去接受数据,串口通讯一定要有协议,否则不好搞,不知道数据到底发完还是没发完######@广隶 : 判断不了,要从协议里规定这次通讯有多少长度的字符。怎么发送根本不好判断,17个字节,可能一次一个字节17次发过来,也可一次性发过来,甚至首位加几个字符发过来。所以写一定要有协议在里面规定通讯到底有多长。######串口方面的东西我最近才接触,我写的这个第一次打印可以一次打印17位内的数据,以后就打印14位后剩下的另起一行打印,14位后的数据好像是又读了一遍串口。怎么去判断接收器能接受多少位的数据?请指教。######对于分给终端的数据一般是有限制的,不能发太多,否则终端会吃不消。这个要看设备的制造商的文档了。######

    我把代码贴出来,有哪位大牛帮我看看,谢谢啦!

    public class Test3 {

    private static String str;

    public void init(){

    try {

    CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1");

    System.out.println(portId.getName()+":开启啦");

    @SuppressWarnings("unused")

           ReadCom readCom =new ReadCom(portId);

    } catch (NoSuchPortException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (PortInUseException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public class ReadCom implements Runnable,SerialPortEventListener{

    InputStream input = System.in;

    SerialPort serialPort;

    Thread readThread;

    public ReadCom(CommPortIdentifier portId) throws PortInUseException, IOException{

    serialPort = (SerialPort) portId.open("test",2000);

    serialPort.setInputBufferSize(1024);

    input=serialPort.getInputStream();

    try {

    serialPort.addEventListener(this);

    } catch (TooManyListenersException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    serialPort.notifyOnDataAvailable(true);

    try {

    serialPort.setSerialPortParams(115200, 

    SerialPort.DATABITS_8, 

    SerialPort.STOPBITS_1, 

    SerialPort.PARITY_NONE);

    } catch (UnsupportedCommOperationException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    readThread = new Thread(this);

    readThread.start();

    }

    @Override

    public void run() {

    // TODO Auto-generated method stub

    }

    @Override

    public void serialEvent(SerialPortEvent event) {

    switch (event.getEventType()) {

    case SerialPortEvent.BI:

    case SerialPortEvent.OE:

    case SerialPortEvent.FE:

    case SerialPortEvent.PE:

    case SerialPortEvent.CD:

    case SerialPortEvent.CTS:

    case SerialPortEvent.DSR:

    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:

    break;

    case SerialPortEvent.DATA_AVAILABLE:

    byte[] readBuffer  =  new byte[512];   

    try {

    while (input.available()>0) {

    int len = input.read(readBuffer);

    str = new String(readBuffer,0,len);

    Memcached mcc = Memcached.getInstance();

    mcc.add("test", str);

    System.out.println("内容长度:"+len);

    System.out.println("内容:"+str);

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    }

    public static void main(String[] args) throws IOException {

    Test3 test3 = new Test3();

    test3.init();

    }

    }


    ######

    引用来自“广隶”的答案

    我把代码贴出来,有哪位大牛帮我看看,谢谢啦!

    public class Test3 {

    private static String str;

    public void init(){

    try {

    CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1");

    System.out.println(portId.getName()+":开启啦");

    @SuppressWarnings("unused")

           ReadCom readCom =new ReadCom(portId);

    } catch (NoSuchPortException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (PortInUseException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public class ReadCom implements Runnable,SerialPortEventListener{

    InputStream input = System.in;

    SerialPort serialPort;

    Thread readThread;

    public ReadCom(CommPortIdentifier portId) throws PortInUseException, IOException{

    serialPort = (SerialPort) portId.open("test",2000);

    serialPort.setInputBufferSize(1024);

    input=serialPort.getInputStream();

    try {

    serialPort.addEventListener(this);

    } catch (TooManyListenersException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    serialPort.notifyOnDataAvailable(true);

    try {

    serialPort.setSerialPortParams(115200, 

    SerialPort.DATABITS_8, 

    SerialPort.STOPBITS_1, 

    SerialPort.PARITY_NONE);

    } catch (UnsupportedCommOperationException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    readThread = new Thread(this);

    readThread.start();

    }

    @Override

    public void run() {

    // TODO Auto-generated method stub

    }

    @Override

    public void serialEvent(SerialPortEvent event) {

    switch (event.getEventType()) {

    case SerialPortEvent.BI:

    case SerialPortEvent.OE:

    case SerialPortEvent.FE:

    case SerialPortEvent.PE:

    case SerialPortEvent.CD:

    case SerialPortEvent.CTS:

    case SerialPortEvent.DSR:

    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:

    break;

    case SerialPortEvent.DATA_AVAILABLE:

    byte[] readBuffer  =  new byte[512];   

    try {

    while (input.available()>0) {

    int len = input.read(readBuffer);

    str = new String(readBuffer,0,len);

    Memcached mcc = Memcached.getInstance();

    mcc.add("test", str);

    System.out.println("内容长度:"+len);

    System.out.println("内容:"+str);

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    }

    public static void main(String[] args) throws IOException {

    Test3 test3 = new Test3();

    test3.init();

    }

    }


    你这样是可以收到收据的,但是使用串口设备的终端机往往都是单片机,性能极为有限,往往不会一次发送大量数据,所以收到的数据基本都是碎片一块一块的。

    在串口接收数据的时候需要一个协议,用这个协议来确保数据的正确性,比如数据长度,那么你就可以先直到长度,然后不停接收数据直到收完为止,另外协议还可以保证双发同步性,如果串口双方同时往对方发数据,这个时候可能会造成不可预料的结果。

    ######

    引用来自“Monkey”的答案

    引用来自“广隶”的答案

    我把代码贴出来,有哪位大牛帮我看看,谢谢啦!

    public class Test3 {

    private static String str;

    public void init(){

    try {

    CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1");

    System.out.println(portId.getName()+":开启啦");

    @SuppressWarnings("unused")

           ReadCom readCom =new ReadCom(portId);

    } catch (NoSuchPortException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (PortInUseException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public class ReadCom implements Runnable,SerialPortEventListener{

    InputStream input = System.in;

    SerialPort serialPort;

    Thread readThread;

    public ReadCom(CommPortIdentifier portId) throws PortInUseException, IOException{

    serialPort = (SerialPort) portId.open("test",2000);

    serialPort.setInputBufferSize(1024);

    input=serialPort.getInputStream();

    try {

    serialPort.addEventListener(this);

    } catch (TooManyListenersException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    serialPort.notifyOnDataAvailable(true);

    try {

    serialPort.setSerialPortParams(115200, 

    SerialPort.DATABITS_8, 

    SerialPort.STOPBITS_1, 

    SerialPort.PARITY_NONE);

    } catch (UnsupportedCommOperationException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    readThread = new Thread(this);

    readThread.start();

    }

    @Override

    public void run() {

    // TODO Auto-generated method stub

    }

    @Override

    public void serialEvent(SerialPortEvent event) {

    switch (event.getEventType()) {

    case SerialPortEvent.BI:

    case SerialPortEvent.OE:

    case SerialPortEvent.FE:

    case SerialPortEvent.PE:

    case SerialPortEvent.CD:

    case SerialPortEvent.CTS:

    case SerialPortEvent.DSR:

    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:

    break;

    case SerialPortEvent.DATA_AVAILABLE:

    byte[] readBuffer  =  new byte[512];   

    try {

    while (input.available()>0) {

    int len = input.read(readBuffer);

    str = new String(readBuffer,0,len);

    Memcached mcc = Memcached.getInstance();

    mcc.add("test", str);

    System.out.println("内容长度:"+len);

    System.out.println("内容:"+str);

    }

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    }

    public static void main(String[] args) throws IOException {

    Test3 test3 = new Test3();

    test3.init();

    }

    }


    你这样是可以收到收据的,但是使用串口设备的终端机往往都是单片机,性能极为有限,往往不会一次发送大量数据,所以收到的数据基本都是碎片一块一块的。

    在串口接收数据的时候需要一个协议,用这个协议来确保数据的正确性,比如数据长度,那么你就可以先直到长度,然后不停接收数据直到收完为止,另外协议还可以保证双发同步性,如果串口双方同时往对方发数据,这个时候可能会造成不可预料的结果。

    谢谢你Monkey,我这个问题解决了!是你的答案给我启示。。。
    ######我再补充一点,有些设备会往里加数据。特别是首位添加额外的字节,当然有些肯是故意加上去保证完整数据都会发过来。######

    楼主,您好!您后来是怎么解决的,能不能把源代码发给我,我邮箱是1416149633@QQ.COM,不尽感激,我是位自学者。

    ######楼主解决了吗?求解决思路
    2020-06-07 22:36:33
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载