获取windows中活跃的Com口

2023-11-08

获取windows中活跃的Com口

记录于2021年11月9日
今天对我来说是个很特殊的一天,母胎SOLO二十一周年(无奈 Orz),闲暇之余写下此文章,记录一下我的日常



前言

这几天做的项目与硬件有点干系,需要用java与串口完成通信,当然完成通信前需要找到系统中活跃串口,今天给大家介绍一下如何找到活跃串口,本文用的包是javacomm20-win32,这个包比较老,若读者的电脑是64位,建议使用RXTX包,这两个包几乎是一样的。
包如何安装本文不做赘述,网上安装教程很多


以下是本篇文章正文内容,下面案例可供参考
若大佬们发现本文不正确的地方,请私信斧正!(抱拳)

一、如何寻找活跃COM口?

要想找到活跃COM口,我们需要时刻关注COM口状态的变化,当某个COM口状态发生改变,我们就认为此COM口为活跃COM口,所以,在我们的程序运行的最初,需要记录下所有COM口的状态,然后用线程去检测COM

二、代码实现

1.导入包

import javax.comm.*;	//使用Com20的需要导入的包
//import gnu.io.*;		//使用RXTX需要导入的包
import java.util.*;
import java.util.concurrent.*

2.获取初始COM口

	Enumeration portList;	//保存所有Com口的枚举类型对象
	HashSet<CommPortIdentifier> before = new HashSet<CommPortIdentifier>(),	//保存初始COM口
								after = new HashSet<CommPortIdentifier>();	//保存监控时依旧存在的COM口
	CommPortIdentifier portId;	
	
	portList = CommPortIdentifier.getPortIdentifiers();	//获取程序最初运行时的com口	
	while (portList.hasMoreElements()) {
		portId = (CommPortIdentifier) portList.nextElement();	
		before.add(portId);		//将初始Com口添加到集合
	}

3.监控线程

public void run(){
		ArrayList<CommPortIdentifier> addarray = new ArrayList<CommPortIdentifier>(),	//保存新增的COM口
									deletearray = new ArrayList<CommPortIdentifier>();	//保存被删除的COM口
		for(;;){	//需要让此线程一直监控
			portList = CommPortIdentifier.getPortIdentifiers();		//重新获取当前所有Com口的枚举
			while (portList.hasMoreElements()){
				after.add((CommPortIdentifier) portList.nextElement());	//保存重新获得的COM口
			}
			/**
			*遍历重新获取Com口的集合,如果改变后的某个COM在初始COM口集合中没有发现,
			*则意味此COM口是新增的COM口,并把此COM口添加至顺序表中保存
			*/
			for(CommPortIdentifier ci : after){		
				if(!before.contains(ci)){	
					//获取到COM口后可以与其建立IO,实现数据的发送和接受,这里只打印出COM口名
					System.out.println("添加了  "+ ci.getName()+"  Com口");	
					addarray.add(ci);			//向保存已添加的com顺序表中添加
				}
			}
			if(addarray.size()==0){		//若遍历结束,且顺序表中无元素,则意味没有找到新添加的COM口
				System.out.println("尚未找到添加的Com口");
			}
			for(CommPortIdentifier ci : before){
				if(!after.contains(ci)){
					System.out.println("移除了  "+ ci.getName()+"  Com口");
					deletearray.add(ci);		//向保存已删除顺序表中添加
				}
			}
			if(deletearray.size()==0){
				System.out.println("尚未找到被移除的Com口");
			}
			
			for(CommPortIdentifier ci : addarray)		//更新初始Com集合
				before.add(ci);
			for(CommPortIdentifier ci : deletearray)
				before.remove(ci);
			after.clear();
			addarray.clear();
			deletearray.clear();
			try{
				Thread.sleep(1000);			//每次检测的时间间隔为1秒(时间可更改)
			}catch(InterruptedException ie){
				ie.printStackTrace();
			}
		}
	}

3.完整代码

import javax.comm.*;
//import gnu.io.*;	
import java.util.*;
import java.util.concurrent.*;

class ComDetect implements Runnable{
	Enumeration portList;
	SerialPort serialPort;
	HashSet<CommPortIdentifier> before = new HashSet<CommPortIdentifier>(),
								after = new HashSet<CommPortIdentifier>();
	CommPortIdentifier portId;	

	ComDetect(){
		portList = CommPortIdentifier.getPortIdentifiers();	
		while (portList.hasMoreElements()) {
			portId = (CommPortIdentifier) portList.nextElement();	
			before.add(portId);		
		}
	}

	@Override
	public void run(){
		ArrayList<CommPortIdentifier> addarray = new ArrayList<CommPortIdentifier>(),
									deletearray = new ArrayList<CommPortIdentifier>();
		for(;;){
			portList = CommPortIdentifier.getPortIdentifiers();		
			while (portList.hasMoreElements()){
				after.add((CommPortIdentifier) portList.nextElement());	
			}
			for(CommPortIdentifier ci : after){
				if(!before.contains(ci)){
					System.out.println("添加了  "+ ci.getName()+"  Com口");
					addarray.add(ci);			
				}
			}
			if(addarray.size()==0){
				System.out.println("尚未找到添加的Com口");
			}
			for(CommPortIdentifier ci : before){
				if(!after.contains(ci)){
					System.out.println("移除了  "+ ci.getName()+"  Com口");
					deletearray.add(ci);		
				}
			}
			if(deletearray.size()==0){
				System.out.println("尚未找到被移除的Com口");
			}
			
			for(CommPortIdentifier ci : addarray)		
				before.add(ci);
			for(CommPortIdentifier ci : deletearray)
				before.remove(ci);
			after.clear();
			addarray.clear();
			deletearray.clear();
			try{
				Thread.sleep(1000);			
			}catch(InterruptedException ie){
				ie.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args){
		ExecutorService exec = Executors.newCachedThreadPool();		//用执行器为我们托管线程
		exec.execute(new Thread(new ComDetect()));
	}
}


总结

提示:这里对文章进行总结:
以上就是今天要讲的内容,本文仅仅简单介绍了如何找到活跃COM口而未对获取COM做任何处理,读者可按需加上处理的代码片。
觉得本文对自己有帮助,请点个免费的赞还有留下评论吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取windows中活跃的Com口 的相关文章

  • Java中字符串中特殊字符的替换

    Java中如何替换字符串 E g String a adf sdf 如何替换和避免特殊字符 您可以删除除此之外的所有字符可打印的 ASCII 范围 http en wikipedia org wiki ASCII ASCII printab
  • Eclipse 在源代码管理中保存操作

    我们希望找到一种在签入之前执行代码标准的 轻量级 方法 我们真的很喜欢使用 Eclipse 内置的想法保存操作 go to Preferences gt gt Java gt gt Editor gt gt Save Actions 其中有
  • Hibernate注解放置问题

    我有一个我认为很简单的问题 我见过两种方式的例子 问题是 为什么我不能将注释放在字段上 让我举一个例子 Entity Table name widget public class Widget private Integer id Id G
  • 这个函数(for循环)空间复杂度是O(1)还是O(n)?

    public void check 10 for string i list Integer a hashtable get i if a gt 10 hashtable remove i 这是 O 1 还是 O n 我猜测 O n 但不是
  • Java:如何从转义的 URL 获取文件?

    我收到了一个定位本地文件的 URL 事实上我收到的 URL 不在我的控制范围内 URL 按照 RFC2396 中的定义进行有效转义 如何将其转换为 Java File 对象 有趣的是 URL getFile 方法返回一个字符串 而不是文件
  • org.apache.sling.api.resource,version=[2.3,3) -- 无法解析

    您好 我无法访问我的项目内容 我已经上传了从 CQ 访问内容所需的所有包 我唯一能看到的是 org apache sling api resource version 2 3 3 无法解析 这是否是异常的原因 如果是 请告诉我如何解决 中Q
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • java中如何连接字符串

    这是我的字符串连接代码 StringSecret java public class StringSecret public static void main String args String s new String abc s co
  • JavaFX 中具有自定义内容的 ListView

    How i can make custom ListView with JavaFx for my app I need HBox with image and 2 Labels for each line listView 您可以通过查看
  • 如何在不超过最大值的情况下增加变量?

    我正在为学校开发一个简单的视频游戏程序 我创建了一个方法 如果调用该方法 玩家将获得 15 点生命值 我必须将生命值保持在最大值 100 并且由于我目前的编程能力有限 我正在做这样的事情 public void getHealed if h
  • 使用 AES SecretKey 的 Java KeyStore setEntry()

    我目前正在 Java 中开发一个密钥处理类 特别是使用 KeyStore 我正在尝试使用 AES 实例生成 SecretKey 然后使用 setEntry 方法将其放入 KeyStore 中 我已经包含了代码的相关部分 The KS Obj
  • hibernate锁等待超时超时;

    我正在使用 Hibernate 尝试模拟对数据库中同一行的 2 个并发更新 编辑 我将 em1 getTransaction commit 移至 em1 flush 之后我没有收到任何 StaleObjectException 两个事务已成
  • 在 Netbeans 8 上配置 JBoss EAP 的问题

    我已经下载了 JBoss EAP 7 并正在 Netbeans 8 上配置它 我已经到达向导 实例属性 其中要求从选择框中选择 域 当我打开选择框时 它是空的 没有什么可以选择的 因此 完成 按钮也处于非活动状态 这使得无法完成配置 我通过
  • 如何使用 Maven 打包并运行具有依赖项的简单命令行应用程序?

    我对 java 和 Maven 都是全新的 所以这可能非常简单 如果我遵循maven2hello world此处的说明 http maven apache org guides getting started maven in Five m
  • 编辑文件名在 JComboBox 中的显示方式,同时保持对文件的访问

    我对 Java 很陌生 对堆栈溢出也很陌生 我正在尝试利用 JMF API 创建一个用 Java 编码的简单媒体播放器 到目前为止 我已经能够设置一个简单的队列 播放列表来使用JComboBox called playListHolder
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • GUI Java 程序 - 绘图程序

    我一直试图找出我的代码有什么问题 这个想法是创建一个小的 Paint 程序并具有红色 绿色 蓝色和透明按钮 我拥有我能想到的让它工作的一切 但无法弄清楚代码有什么问题 该程序打开 然后立即关闭 import java awt import
  • 如何在 JFreeChart 中设置多个系列的线条粗细?

    我创建了很多图表 在他们每个人中我都需要打电话 renderer setSeriesStroke i new BasicStroke 2 0f 对于每个系列 renderer is chart getXYPlot getRenderer 我

随机推荐

Powered by Hwhale