Java 跨平台获取 MAC 地址的两种方法
前言
有時我們因為軟件授權或者其它需要獲取主機唯一標識而需要獲取用戶主機的MAC地址,而本文則將介紹如何通過Java來實現(xiàn)跨平臺獲取MAC地址的兩種方法,同時具體的代碼也已上傳到GitHub。
如果不希望將 GitHub 的代碼克隆到本地查看,但是又無法忍受在網頁查看代碼時無限的鏈接嵌套,可以嘗試在網址的 GitHub 單詞后加上 1s,即可在網頁中有通過 VSCode 查看代碼的效果,例如本文是 https://github1s.com/zhangjiwei1221/blog/blob/master/mac,如下圖所示:
使用 NetworkInterface 類
首先介紹如何通過Java的NetworkInterface類的API來獲取本機MAC地址的方法,首先展示代碼:
/*** 獲取 mac 地址工具類 v1 版** @date 2021/5/13* @author zjw*/ public class MacUtil {public static void main(String[] args) {getMac().forEach(System.out::println);}/*** 獲取本機 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();}}通過以上代碼理論上即可獲取本機所有的MAC地址,此外通過format方法可以將獲取到的MAC地址統(tǒng)一處理成XX-XX-XX-XX-XX-XX的格式,這里之所以說是理論上,是因為我曾經在別人的蘋果電腦上運行,結果并沒有得到所有MAC地址(沒有得到執(zhí)行ifconfig -a得到的所有MAC地址,而且還會出現(xiàn)llw0這個網絡的MAC地址一直變動),但是我在本地的虛擬機中運行蘋果時卻也是正常,由于我自己沒有蘋果電腦,所以暫時也不清楚具體的原因,如果有知道的小伙伴,歡迎留言,提前感謝啦~~~
執(zhí)行命令行獲取
正如在上一部分中提到的,在某些情況下使用NetworkInterface類并不能獲取到本機所有的MAC地址,甚至還可能出現(xiàn)動態(tài)變化的情況(暫時不清楚原因)。因此,在這種情況下只能通過Java的Runtime類的exec方法直接執(zhí)行命令了,當然在大多數(shù)情況下還是建議使用NetworkInterface類,不僅方便,而且萬一以后修復了上面的bug(不知道算不算是bug,還是我個人的問題),不對上述代碼做任何變動就可以得到自己執(zhí)行命令的效果了,說了那么多,先看看如果通過自己執(zhí)行命令獲取本機的所有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);}/*** 根據不同操作系統(tǒng)執(zhí)行不同命令* 獲取本機 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();}/*** 通過正則表達式提取執(zhí)行命令得到的結果集中的 mac 地址* 并調整得到的 mac 地址的格式** @param command 查看網絡信息的命令** @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í)行命令并得到結果的每一行組成的字符串數(shù)組** @param command 查看網絡信息的命令** @return 執(zhí)行命令返回的所有數(shù)據行*/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í)行命令并結合正則表達式獲取本機所有MAC地址的方法,代碼如有錯誤不當之處,歡迎留言指正。
總結
本文簡單介紹了兩種跨平臺獲取MAC地址的方法,不過仍然存在一些尚未解決的問題,希望有了解的朋友能夠留言告訴我,感激不盡!
參考資料
洪勇軍.Java實現(xiàn)跨平臺的MAC地址讀取[J].電腦編程技巧與維護,2009(17):52-53.
總結
以上是生活随笔為你收集整理的Java 跨平台获取 MAC 地址的两种方法的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 单片机---HLK-W801移植Nes模
- 下一篇: 2017-AHU校赛网络赛解题报告
