我成功安装并测试了 Java Comm API。 我可以通过串口发送和接收数据。 但问题是,每个字符前面多了19个空格。 当我尝试使用 super 终端时,多余的空格不存在。
例如:
+CENG:0,"0021,37,99,404,46,36,0000,05,05,77,255"
预计。但是Java程序输出它时每个字符前都有空格
+ E N
代码是:
import java.io.*;
import java.util.*;
import javax.comm.*;
public class SimpleRead implements Runnable, SerialPortEventListener
{
static CommPortIdentifier portId;
static Enumeration portList;
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
public static void main(String[] args) throws Exception
{
portList = CommPortIdentifier.getPortIdentifiers();
System.out.println("SimpleRead Started.");
while (portList.hasMoreElements())
{
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)
{
System.out.println ("Found " + portId.getName());
if (portId.getName().equals("COM5"))
{
OutputStream outputStream;
SerialPort writePort = (SerialPort) portId.open("SimpleWriteApp", 2000);
writePort.setSerialPortParams(2400,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
outputStream = writePort.getOutputStream();
outputStream.write("AT+CENG=2".getBytes());
writePort.close();
SimpleRead reader = new SimpleRead();
}
}
}
}
public SimpleRead()
{
try
{
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
}
catch (PortInUseException e)
{
e.printStackTrace();
}
try
{
inputStream = serialPort.getInputStream();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
serialPort.addEventListener(this);
}
catch (TooManyListenersException e)
{
e.printStackTrace();
}
serialPort.notifyOnDataAvailable(true);
try
{
serialPort.setSerialPortParams(2400, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}
catch (UnsupportedCommOperationException e)
{
e.printStackTrace();
}
readThread = new Thread(this);
readThread.start();
}
public void run()
{
try
{
Thread.sleep(20000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
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.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[20];
try
{
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
}
System.out.print(new String(readBuffer));
}
catch (IOException e)
{
e.printStackTrace();
}
break;
}
}
}
最佳答案
在您的代码中(出于示例目的,删除了异常处理):
byte[] readBuffer = new byte[20];
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
}
System.out.print(new String(readBuffer));
您有一个 20 字节的缓冲区,无论您读取多少数据,您都会从所有 20 个字节构造一个 String
。在 Java 中,String
可以包含空值,因此您的字符串最终会是一个字符后跟 19 个空值。然后,当您打印它时,您的特定控制台将显示空格而不是空值。
有几点需要注意。首先,目前还不清楚你想用这个循环做什么。无论流上还剩下多少字节,您都会重复读入同一个 20 字节缓冲区(例如,如果有 400 字节要读取,则最多 readBuffer
以最后 20 个字节结束)。
其次,为了解决我刚才描述的字符串问题,您只想使用实际从 readBuffer
读取的字节,即缓冲区的前 numBytes
字节。
第三,在从原始字节构造 String
时,您应该始终指定字符编码。对于您的数据,似乎 us-ascii
是合适的。
例如,这样的事情:
byte[] readBuffer = new byte[20];
while (inputStream.available() > 0) {
int numBytes = inputStream.read(readBuffer);
System.out.print(new String(readBuffer, 0, numBytes, "us-ascii"));
}
关于Java 通信 API 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18201079/