原文链接:https://www.cnblogs.com/new-life/p/9345849.html
没想到挺多人需要这个的,很高兴这篇文章能对大家有帮助,主要的工具类博文里已经有了,当然,要小工具源码的留言邮箱即可。
最近接触到了串口及其读写,在此记录java进行串口读写的过程。
1.导入支持java串口通信的jar包:
在maven项目的pom.xml中添加RXTXcomm的依赖 或者 下载RXTXcomm.jar并导入到项目中。
支持Java串口通信操作的jar包,java.comm比较老,而且不支持64位系统,推荐使用Rxtx这个jar包(32位/64位均支持)。
下载地址:
http://files.cnblogs.com/files/Dreamer-1/mfz-rxtx-2.2-20081207-win-x86.zip (32位)
http://files.cnblogs.com/files/Dreamer-1/mfz-rxtx-2.2-20081207-win-x64.zip (64位)
注意:运行过程中抛出 java.lang.UnsatisfiedLinkError 错误或 gnu.io 下的类找不到时,将rxtx解压包中的 rxtxParallel.dll,rxtxSerial.dll 这两个文件复制到 C:\Windows\System32 目录下可解决该错误。(这个需要注意自己电脑的位数)
2.编写代码操作串口:
串口必要参数类:包含连接串口所必须的参数,方便在调用串口时设置和传递串口参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public class ParamConfig {
private String serialNumber; private int baudRate; private int checkoutBit; private int dataBit; private int stopBit; public ParamConfig() {}
public ParamConfig(String serialNumber, int baudRate, int checkoutBit, int dataBit, int stopBit) { this.serialNumber = serialNumber; this.baudRate = baudRate; this.checkoutBit = checkoutBit; this.dataBit = dataBit; this.stopBit = stopBit; } getter()... setter()... }
|
串口操作类:(其中包含的CustomException是自定义异常类,仅用于抛出异常原因。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
| import gnu.io.CommPortIdentifier; import gnu.io.PortInUseException; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException;
public class SerialPortUtils implements SerialPortEventListener { private CommPortIdentifier commPortId; private Enumeration<CommPortIdentifier> portList; private SerialPort serialPort; private InputStream inputStream; private OutputStream outputStream; private String data; private String dataHex;
@SuppressWarnings("unchecked") public void init(ParamConfig paramConfig) { portList = CommPortIdentifier.getPortIdentifiers(); boolean isExsist = false; while (portList.hasMoreElements()) { commPortId = portList.nextElement(); if (commPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) { if (paramConfig.getSerialNumber().equals(commPortId.getName())) { isExsist = true; try { serialPort = (SerialPort) commPortId.open(Object.class.getSimpleName(), 2000); serialPort.addEventListener(this); serialPort.notifyOnDataAvailable(true); serialPort.setSerialPortParams(paramConfig.getBaudRate(), paramConfig.getDataBit(), paramConfig.getStopBit(), paramConfig.getCheckoutBit()); } catch (PortInUseException e) { throw new CustomException("端口被占用"); } catch (TooManyListenersException e) { throw new CustomException("监听器过多"); } catch (UnsupportedCommOperationException e) { throw new CustomException("不支持的COMM端口操作异常"); } break; } } } if (!isExsist) { throw new CustomException("不存在该串口!"); } }
@Override 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: readComm(); break; default: break; } }
public void readComm() { try { inputStream = serialPort.getInputStream(); byte[] readBuffer = new byte[inputStream.available()]; int len = 0; while ((len = inputStream.read(readBuffer)) != -1) { data = new String(readBuffer, 0, len).trim(); dataHex = bytesToHexString(readBuffer); System.out.println("data:" + data); System.out.println("dataHex:" + dataHex); inputStream.close(); inputStream = null; break; } } catch (IOException e) { throw new CustomException("读取串口数据时发生IO异常"); } }
public void sendComm(String data) { byte[] writerBuffer = null; try { writerBuffer = hexToByteArray(data); } catch (NumberFormatException e) { throw new CustomException("命令格式错误!"); } try { outputStream = serialPort.getOutputStream(); outputStream.write(writerBuffer); outputStream.flush(); } catch (NullPointerException e) { throw new CustomException("找不到串口。"); } catch (IOException e) { throw new CustomException("发送信息到串口时发生IO异常"); } }
public void closeSerialPort() { if (serialPort != null) { serialPort.notifyOnDataAvailable(false); serialPort.removeEventListener(); if (inputStream != null) { try { inputStream.close(); inputStream = null; } catch (IOException e) { throw new CustomException("关闭输入流时发生IO异常"); } } if (outputStream != null) { try { outputStream.close(); outputStream = null; } catch (IOException e) { throw new CustomException("关闭输出流时发生IO异常"); } } serialPort.close(); serialPort = null; } }
public String getDataHex() { String result = dataHex; dataHex = null; return result; }
public String getData() { String result = data; data = null; return result; }
public static byte hexToByte(String inHex) { return (byte) Integer.parseInt(inHex, 16); }
public static byte[] hexToByteArray(String inHex) { int hexlen = inHex.length(); byte[] result; if (hexlen % 2 == 1) { hexlen++; result = new byte[(hexlen / 2)]; inHex = "0" + inHex; } else { result = new byte[(hexlen / 2)]; } int j = 0; for (int i = 0; i < hexlen; i += 2) { result[j] = hexToByte(inHex.substring(i, i + 2)); j++; } return result; }
public static final String bytesToHexString(byte[] bArray) { StringBuffer sb = new StringBuffer(bArray.length); String sTemp; for (int i = 0; i < bArray.length; i++) { sTemp = Integer.toHexString(0xFF & bArray[i]); if (sTemp.length() < 2) sb.append(0); sb.append(sTemp.toUpperCase()); } return sb.toString(); } }
|
调用串口操作类的代码:
1 2 3 4 5 6 7 8 9 10 11 12
| public static void main(String[] args) { SerialPortUtils serialPort = new SerialPortUtils(); ParamConfig paramConfig = new ParamConfig("COM4", 9600, 0, 8, 1); serialPort.init(paramConfig); serialPort.sendComm("FEF10A000000000000000AFF"); serialPort.closeSerialPort(); }
|
当执行main方法中的代码且未执行关闭串口时,程序将一直处于开启状态,自动监听,接收读取来自串口的数据。
注意:一个串口只能打开一次,并只支持一个程序调用。
以上所记录的是简单测试java是否能成功操作串口数据,至于本人所写的Web端的读卡器调试功能则是在串口操作类的基础上编写网页界面,通过请求来控制串口的开启关闭及相应的设置,功能比较简单,放个界面记录一下: