從早期的 Modem、滑鼠/鍵盤,到現代的 USB、工業儀器、醫療設備、網路設備,串列通訊(RS-232/485/422、USB)始終是硬體互聯的基石。Java 標準庫未內建串口支援,需引入 Java Communications API (comm.jar)。本文涵蓋 RS-232 基礎、API 安裝、核心類別、輪詢與事件驅動兩種讀取模式,並提供完整可運行程式碼。
comm.jar → $JAVA_HOME/jre/lib/ext/win32com.dll → 應用程式工作目錄(user.dir)或 $JAVA_HOME/jre/bin/javax.comm.properties → $JAVA_HOME/jre/lib/Linux 平台請參考 RXTX 專案。
javax.comm 套件)| 類別/介面 | 職責 |
|---|---|
CommPortIdentifier | 列舉、開啟、管理埠佔用權 |
CommPort | 父介面,提供 getInputStream()/getOutputStream() |
SerialPort | 串口專用,設定鮑率、資料位、停止位、校驗位、流控 |
SerialPortEventListener | 事件驅動模式的監聽器介面 |
Enumeration<CommPortIdentifier> ports = CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements()) {
CommPortIdentifier pid = ports.nextElement();
if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL) {
System.out.println("可用串口: " + pid.getName()); // 例: COM1, COM2
}
}
CommPortIdentifier pid = CommPortIdentifier.getPortIdentifier("COM1");
SerialPort port = (SerialPort) pid.open("MyApp", 2000); // 2 秒逾時
port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
InputStream in = port.getInputStream();
OutputStream out = port.getOutputStream();
// 讀寫邏輯...
port.close(); // 釋放埠
public class PollingReader extends Thread {
private InputStream in;
private volatile boolean stop = false;
public void run() {
StringBuffer buf = new StringBuffer();
try {
while (!stop) {
int ch = in.read();
if (ch == 'Q' || ch == 'q') { stop = true; break; }
buf.append((char) ch);
}
} catch (IOException ignored) {}
}
}
public class EventReader implements SerialPortEventListener {
private SerialPort port;
public EventReader(SerialPort port) {
this.port = port;
port.addEventListener(this);
port.notifyOnDataAvailable(true);
}
public void serialEvent(SerialPortEvent e) {
if (e.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try (InputStream in = port.getInputStream()) {
int ch; StringBuffer buf = new StringBuffer();
while ((ch = in.read()) > 0) buf.append((char) ch);
System.out.println("收到: " + buf);
} catch (IOException ex) { ex.printStackTrace(); }
}
// 其他事件: CTS, DSR, BI, OE, PE, FE, RI, OUTPUT_BUFFER_EMPTY 等
}
}
close() 釋放埠,否則後續開啟會拋 PortInUseException。SerialPort 時需自行同步。Java Communications API 雖歷史悠久,但其事件驅動模型與標準串流介面設計經典,掌握後可輕鬆整合各類串口設備。現代專案建議改用積極維護的 jSerialComm,API 相似且跨平台支援更佳。