Java 跨平台获取 MAC 地址的两种方法
前言
有時(shí)我們因?yàn)檐浖跈?quán)或者其它需要獲取主機(jī)唯一標(biāo)識(shí)而需要獲取用戶主機(jī)的MAC地址,而本文則將介紹如何通過Java來實(shí)現(xiàn)跨平臺(tái)獲取MAC地址的兩種方法,同時(shí)具體的代碼也已上傳到GitHub。
如果不希望將 GitHub 的代碼克隆到本地查看,但是又無法忍受在網(wǎng)頁查看代碼時(shí)無限的鏈接嵌套,可以嘗試在網(wǎng)址的 GitHub 單詞后加上 1s,即可在網(wǎng)頁中有通過 VSCode 查看代碼的效果,例如本文是 https://github1s.com/zhangjiwei1221/blog/blob/master/mac,如下圖所示:
使用 NetworkInterface 類
首先介紹如何通過Java的NetworkInterface類的API來獲取本機(jī)MAC地址的方法,首先展示代碼:
/*** 獲取 mac 地址工具類 v1 版** @date 2021/5/13* @author zjw*/ public class MacUtil {public static void main(String[] args) {getMac().forEach(System.out::println);}/*** 獲取本機(jī) mac 地址集合** @return mac 地址集合*/public static List<String> getMac() {List<String> list = new ArrayList<>();try {Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();while (networkInterfaces.hasMoreElements()) {NetworkInterface networkInterface = networkInterfaces.nextElement();Optional.ofNullable(networkInterface.getHardwareAddress()).ifPresent(mac -> list.add(format(mac)));}} catch (Exception e) {e.printStackTrace();}return list;}/*** 將 mac 字節(jié)數(shù)組格式化為全大寫并且使用 - 作為分隔符的字符串** @param mac 獲取到的 mac 字節(jié)數(shù)組** @return 格式化后的 mac 地址*/private static String format(byte[] mac) {StringBuilder sb = new StringBuilder();for (byte b : mac) {sb.append(String.format("%02X", b)).append("-");}sb.deleteCharAt(sb.length() - 1);return sb.toString();}}通過以上代碼理論上即可獲取本機(jī)所有的MAC地址,此外通過format方法可以將獲取到的MAC地址統(tǒng)一處理成XX-XX-XX-XX-XX-XX的格式,這里之所以說是理論上,是因?yàn)槲以?jīng)在別人的蘋果電腦上運(yùn)行,結(jié)果并沒有得到所有MAC地址(沒有得到執(zhí)行ifconfig -a得到的所有MAC地址,而且還會(huì)出現(xiàn)llw0這個(gè)網(wǎng)絡(luò)的MAC地址一直變動(dòng)),但是我在本地的虛擬機(jī)中運(yùn)行蘋果時(shí)卻也是正常,由于我自己沒有蘋果電腦,所以暫時(shí)也不清楚具體的原因,如果有知道的小伙伴,歡迎留言,提前感謝啦~~~
執(zhí)行命令行獲取
正如在上一部分中提到的,在某些情況下使用NetworkInterface類并不能獲取到本機(jī)所有的MAC地址,甚至還可能出現(xiàn)動(dòng)態(tài)變化的情況(暫時(shí)不清楚原因)。因此,在這種情況下只能通過Java的Runtime類的exec方法直接執(zhí)行命令了,當(dāng)然在大多數(shù)情況下還是建議使用NetworkInterface類,不僅方便,而且萬一以后修復(fù)了上面的bug(不知道算不算是bug,還是我個(gè)人的問題),不對(duì)上述代碼做任何變動(dòng)就可以得到自己執(zhí)行命令的效果了,說了那么多,先看看如果通過自己執(zhí)行命令獲取本機(jī)的所有MAC地址吧,先直接展示代碼:
/*** 獲取 mac 地址工具類 v2 版** @date 2021/5/13* @author zjw*/ public class MacUtil {private static final String WIN_PREFIX = "win";private static final String OS_NAME_PROPERTY = "os.name";private static final String WIN_COMMAND = "ipconfig /all";private static final String UNIX_COMMAND = "/sbin/ifconfig -a";private static final String MAC_REGEX = "(([a-f0-9]{2}-){5}|([a-f0-9]{2}:){5})[a-f0-9]{2}";private static final Pattern pattern = Pattern.compile(MAC_REGEX, Pattern.CASE_INSENSITIVE);public static void main(String[] args) {getMac().forEach(System.out::println);}/*** 根據(jù)不同操作系統(tǒng)執(zhí)行不同命令* 獲取本機(jī) mac 地址集合** @return mac 地址集合*/private static List<String> getMac() {try {String osName = System.getProperty(OS_NAME_PROPERTY).toLowerCase();if (osName.startsWith(WIN_PREFIX)) {return getMacByCommand(WIN_COMMAND);}return getMacByCommand(UNIX_COMMAND);} catch (Exception e) {e.printStackTrace();}return Collections.emptyList();}/*** 通過正則表達(dá)式提取執(zhí)行命令得到的結(jié)果集中的 mac 地址* 并調(diào)整得到的 mac 地址的格式** @param command 查看網(wǎng)絡(luò)信息的命令** @return mac 地址集合*/private static List<String> getMacByCommand(String command) throws IOException {List<String> macList = new ArrayList<>();List<String> strList = execCommand(command);for (String str : strList) {Matcher matcher = pattern.matcher(str);if (matcher.find() && matcher.end() == str.length()) {macList.add(matcher.group().replace(":", "-").toUpperCase());}}return macList;}/*** 執(zhí)行命令并得到結(jié)果的每一行組成的字符串?dāng)?shù)組** @param command 查看網(wǎng)絡(luò)信息的命令** @return 執(zhí)行命令返回的所有數(shù)據(jù)行*/private static List<String> execCommand(String command) throws IOException {List<String> strList = new ArrayList<>();Process process = Runtime.getRuntime().exec(command);try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) {return br.lines().collect(Collectors.toList());} catch (Exception e) {e.printStackTrace();}process.destroy();return strList;}}以上便是通過執(zhí)行命令并結(jié)合正則表達(dá)式獲取本機(jī)所有MAC地址的方法,代碼如有錯(cuò)誤不當(dāng)之處,歡迎留言指正。
總結(jié)
本文簡單介紹了兩種跨平臺(tái)獲取MAC地址的方法,不過仍然存在一些尚未解決的問題,希望有了解的朋友能夠留言告訴我,感激不盡!
參考資料
洪勇軍.Java實(shí)現(xiàn)跨平臺(tái)的MAC地址讀取[J].電腦編程技巧與維護(hù),2009(17):52-53.
總結(jié)
以上是生活随笔為你收集整理的Java 跨平台获取 MAC 地址的两种方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 单片机---HLK-W801移植Nes模
- 下一篇: java斗图表情_Java爬取斗图网站的