首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 串口通訊完整指南:javax.comm API 環境配置、讀寫操作與線程模型

     編輯:Java 相關知識

環境搭建 (javax.comm / RXTX)

  1. 下載 javacomm20-win32.zip (或 RXTX rxtx-2.1-7-bins-r2.zip)
  2. 關鍵文件放置:
    • win32com.dll → JDK/bin & JRE/bin
    • comm.jar → JDK/lib & JRE/lib
    • javax.comm.properties → JDK/lib & JRE/lib (內容:Driver=com.sun.comm.Win32Driver)
  3. 驗證:運行枚舉端口程序,輸出 COM1, COM3 等

枚舉可用串口


public static void listPorts() {
    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 ...
        }
    }
}

打開/配置/關閉串口


public class SerialPortManager {
    private SerialPort port;
    private InputStream in;
    private OutputStream out;

    public boolean open(String portName, int baudRate) {
        try {
            CommPortIdentifier pid = CommPortIdentifier.getPortIdentifier(portName);
            port = (SerialPort) pid.open("MyApp", 2000); // 2s 超時
            port.setSerialPortParams(baudRate,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_EVEN);
            port.setInputBufferSize(1024);
            port.setOutputBufferSize(1024);
            in = port.getInputStream();
            out = port.getOutputStream();
            port.notifyOnDataAvailable(true); // 事件驅動可選
            return true;
        } catch (Exception e) { e.printStackTrace(); return false; }
    }

    public void close() {
        try { if (in != null) in.close(); } catch (IOException ignored) {}
        try { if (out != null) out.close(); } catch (IOException ignored) {}
        if (port != null) port.close();
    }
}

讀取數據 (阻塞 / 事件驅動)

阻塞讀取


public String readBlocking() throws IOException {
    byte[] buf = new byte[4096];
    int len = in.read(buf); // 阻塞直到有數據
    if (len <= 0) return null;
    byte[] data = Arrays.copyOf(buf, len);
    return bytesToHex(data); // 轉十六進制字符串便於調試
}

事件驅動 (SerialPortEventListener)


port.addEventListener(new SerialPortEventListener() {
    @Override public void serialEvent(SerialPortEvent e) {
        if (e.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try { processInput(in); } catch (IOException ex) { ex.printStackTrace(); }
        }
    }
});
port.notifyOnDataAvailable(true);

發送數據


public void send(byte[] data) throws IOException {
    out.write(data);
    out.flush();
}

線程模型建議

  • 主線程:UI/業務邏輯
  • 讀取線程:循環 in.read() 或事件回調處理接收
  • 發送隊列:生產者投遞 byte[],單一發送線程串行 out.write() (避免並發寫入錯亂)

現代替代方案

jSerialComm (Fazecast) — 純 Java、無需原生庫安裝、跨平台、API 更簡潔,推薦新項目使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved