繁体   English   中英

从inputStream获取无法识别的字符

[英]Getting unrecognized characters from inputStream

我正在使用java comm api从磅秤读取数据。 下面是代码:

import java.io.*;
import java.util.*;
import javax.comm.*;

public class Parrot implements Runnable, SerialPortEventListener {
    static CommPortIdentifier portId;
    static Enumeration portList;

    InputStream inputStream;
    SerialPort serialPort;
    Thread readThread;

    public static void main(String[] args) {
        portList = CommPortIdentifier.getPortIdentifiers();
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                 if (portId.getName().equals("COM1")) {
                    Parrot reader = new Parrot();
                }
            }
        }
    }

    public Parrot() {
        try {
            serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
        } catch (PortInUseException e) {System.out.println(e);}
        try {
            inputStream = serialPort.getInputStream();
        } catch (IOException e) {System.out.println(e);}
    try {
            serialPort.addEventListener(this);
    } catch (TooManyListenersException e) {System.out.println(e);}
        serialPort.notifyOnDataAvailable(true);
        try {
            serialPort.setSerialPortParams(9600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
        } catch (UnsupportedCommOperationException e) {System.out.println(e);}
        readThread = new Thread(this);
        readThread.start();
    }

    public void run() {
        System.out.println("In the run method");
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {System.out.println(e);}
    }

    public void serialEvent(SerialPortEvent event) {
        switch(event.getEventType()) {
        case SerialPortEvent.DATA_AVAILABLE:
            byte[] readBuffer = new byte[20];

            try {
                int availableBytes =  inputStream.available();
                System.out.println(availableBytes+" bytes are available to read");
                while (inputStream.available() > 0) {
                    int numBytes = inputStream.read(readBuffer);
                }
                System.out.print(new String(readBuffer));
            } catch (IOException e) {System.out.println(e);}
            break;
        }
    }
}

以下是两个屏幕截图,一个来自超级终端,另一个来自上面的java程序:

超级终端(带有终端字体) 在此处输入图片说明

Java程序

在此处输入图片说明

我想获得与超级终端相同的字符。

看起来您没有正确读取流。 你有

        byte[] readBuffer = new byte[20];

        try {
            int availableBytes =  inputStream.available();
            System.out.println(availableBytes+" bytes are available to read");
            while (inputStream.available() > 0) {
                // OVERWRITES THE BYTES FROM THE PREVIOUS READ
                int numBytes = inputStream.read(readBuffer);
            }
            // DOESN'T GIVE BUFFER END POINTS AND DOESN'T GIVE ENCODING
            System.out.print(new String(readBuffer));
        } catch (IOException e) {System.out.println(e);}

应该

        byte[] readBuffer = new byte[20];
        int bytesRead;
        try {
            int availableBytes =  inputStream.available();
            System.out.println(availableBytes+" bytes are available to read");
            while ((bytesRead = inputStream.read(readBuffer)) != -1) {
                System.out.print(new String(readBuffer,0,bytesRead,Charset.forName(ENCODING));
            }

        } catch (IOException e) {System.out.println(e);}

其中ENCODING是正确编码的String ,例如“ UTF-8”。

如果要获取具有所有内容的单个String

        byte[] readBuffer = new byte[20];
        int bytesRead;
        StringBuilder sb = new StringBuilder(100);
        try {
            int availableBytes =  inputStream.available();
            System.out.println(availableBytes+" bytes are available to read");
            while ((bytesRead = inputStream.read(readBuffer) != -1) {
                sb.append(new String(readBuffer,0,bytesRead,Charset.forName(ENCODING));
            }
            System.out.println("The content -> " + sb);

        } catch (IOException e) {System.out.println(e);}

编辑:在这里回答您的评论:如果要按行分隔,则需要在循环内向StringBuilder添加换行。 这些框可能是因为您的编码不正确,或者内容甚至不是有效的字符数据。 我不知道如何以编程方式确定编码。 通常这是您事先知道的。 另一个问题可能是您在设置com端口流时使用的常量

        serialPort.setSerialPortParams(9600,
            SerialPort.DATABITS_8,
            SerialPort.STOPBITS_1,
            SerialPort.PARITY_NONE);

您确定这些是正确的吗?

仅供参考: 编码列表。您需要使用中间列中的值(“ java.io API和java.lang API的规范名称”)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM