简体   繁体   English

从inputStream获取无法识别的字符

[英]Getting unrecognized characters from inputStream

I am reading data from weigh bridge using java comm api . 我正在使用java comm api从磅秤读取数据。 below is the code: 下面是代码:

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;
        }
    }
}

Below are two screen shots, one from hyper terminal and one from above java program: 以下是两个屏幕截图,一个来自超级终端,另一个来自上面的java程序:

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

Java Program Java程序

在此处输入图片说明

I want to get the same characters as hyper terminal. 我想获得与超级终端相同的字符。

It doesn't look like you are correctly reading the stream. 看起来您没有正确读取流。 You have 你有

        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);}

Should be 应该

        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);}

Where ENCODING is a String that is the proper encoding, eg "UTF-8". 其中ENCODING是正确编码的String ,例如“ UTF-8”。

If you want to get a single String that has all of the content: 如果要获取具有所有内容的单个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);}

EDIT: Answering your comment here: If you want to separate by line, you need to add a new-line to the StringBuilder within the loop. 编辑:在这里回答您的评论:如果要按行分隔,则需要在循环内向StringBuilder添加换行。 The boxes are likely because you do not have the proper encoding OR the content isn't even valid character data. 这些框可能是因为您的编码不正确,或者内容甚至不是有效的字符数据。 I don't know how to programmatically determine encoding. 我不知道如何以编程方式确定编码。 It's usually something you know beforehand. 通常这是您事先知道的。 The other problem may be the constants you use when setting up the com port stream 另一个问题可能是您在设置com端口流时使用的常量

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

Are you sure those are correct? 您确定这些是正确的吗?

FYI: A list of encodings .You'll want to use a value from the middle column ("Canonical Name for java.io API and java.lang API"). 仅供参考: 编码列表。您需要使用中间列中的值(“ java.io API和java.lang API的规范名称”)。

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

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