程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 用純JAVA語言編程讀取MAC地址的實現

用純JAVA語言編程讀取MAC地址的實現

編輯:關於JAVA

本文介紹如何在WindowXP/NT/2000環境中,編寫純Java程序,執行外部命令IPCONFIG,並通過分析該命令的輸入流而獲得本機的Mac地址的編程方法。

  1 引言

  用Java編寫的程序,可以很方便地運行在各種平台的環境。但在實際的開發過程中,有時不得不涉及一些底層的編程。比如為了防止軟件盜用,我們希望軟件只能在指定計算機上運行,所以需要程序讀取該機區分於其它計算機的硬件特征,如Mac地址等。作為一種跨平台語言,給Java語言提出了挑戰。本文正是針對該問題,提出一種直接用純Java語言,讀去Mac地址的編程方法。

  我們知道,在每一個Java應用程序中都存在著一個與其運行環境相聯系的Runtime對象。該對象可執行外部命令、查可用內存等。而多數操作系統都提供有查詢該機Mac地址的命令。如在Microsoft的操作系統中,命令IPCONFIG等。本文的思路是在程序中運行一個外部命令,將該命令的運行結果作為一個流(Stream),讀取並分析之,進而實現獲取Mac地址的目的。

  2 Runtime類

  在每一個Java 應用程序裡面,都有惟一的一個Runtime 對象。通過這個Runtime 對象,應用程序可以與其運行環境發生相互作用。

  一般不實例化一個Runtime對象。但是可以通過調用靜態方法Runtime.getRuntime( )而獲得對當前Runtime對象的引用。Runtime 類的大多數方法是實例方法。

  Runtime 對象的作用主要有:執行外部命令;返回空閒內存;運行垃圾回收器;加載動態庫等。

  Applets和其他不可信賴的程序由於沒有引起一個安全異常(SecurityException)而不能調用任何的Runtime方法。

  下面的例子演示了怎樣使用Runtime 對象運行一個外部命令。

以下是引用片段:
: 
  Process process = Runtime.getRuntime().exec("cmd.exe /c dir"); 
  process.waitFor(); 
  :

  Runtime.getRuntime()返回當前應用程序的Runtime對象,該對象的exec()方法指示Java虛擬機創建一個子進程執行指定的可執行程序,並返回與該子進程對應的Process對象實例。通過Process可以控制該子進程的執行或獲取該子進程的信息。第二條語句的目的是等待子進程完成後再往下執行。

  上面的程序在運行時會執行dir命令。如果在Windows95/98下,命令格式可以寫成"command.exe /c dir"。開關/C指明後面跟隨的字符串是命令,並在執行命令後關閉DOS 窗口。

  方法exec還可以打開一個不可執行的程序,但該文件存在關聯的應用程序。以打開一個Word文檔Mydoc.doc文件為例,Java中可以有以下兩種寫法:

以下是引用片段:
 exec(""cmd /E:ON /c start MyDoc.doc""); 
  exec(" c:Program FilesMicrosoft OfficeOfficewinWord.exe .mydoc.doc");

  在第一種方式中,被執行的命令是start Mydoc.doc,開關E:ON 指定DOS 命令處理器允許命令擴展,而start 命令會開啟一個單獨的窗口執行所提供的命令。

執行一個有標准輸出的DOS命令,程序執行完後往往不會自動關閉,從而導致Java應用程序阻塞在waitfor( )。導致該現象的原因可能是該命令的輸出比較多,而運行窗口的輸出緩沖區不夠大。解決的辦法是,利用Java的Process類提供的方法讓Java虛擬機截獲DOS運行的標准輸出,在waitfor()命令之前讀出該緩沖區的內容。以運行命令dir為例,典型的程序如下:

以下是引用片段:
 : 
  String line; 
  Process process = Runtime.getRuntime().exec("cmd /c dir"); 
  BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader(process.getInputStream())); 
  while ( (line = bufferedReader.readLine()) != -1) System. out.println(line); 
  process.waitFor( ); 
  :3 Process

  Runtime.exec方法創建一個本機進程,並返回 Process 子類的一個實例,該實例可用來控制進程並獲取相關信息。

  抽象類Process封裝了一個進程(process),一個正在執行的程序。它主要被當作由Runtime類中的exec( )方法所創建的對象的類型的超類。在抽象類Process中,主要包含了如下一些抽象方法。

  InputStream getInputStream( ):返回一個從進程的out輸出流中讀輸入的輸入流。

  OutputStream getOutputStream( ):返回一個從進程的in輸入流中寫輸出的輸出流。

  int waitFor( ) throws InterruptedException:返回由進程返回的退出碼。這個方法直到調用它的進程中止,才會返回。

  4 程序編寫

  我們先來分析ipconfig/all的輸出格式:

  圖1
點擊放大此圖片

  從圖1中我們看到MAC地址包含的行為:“ Physical Address. . . . . . . . . : 00-10-DC-A9-0B-2C”。為了找到MAC地址,我們一行一行讀取字符,只要找到字符串“ Physical Address. . . . . . . . . :”,就可以找到Mac地址了。下面是實現的程序片段:

以下是引用片段:
: 
  Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all"); 
  BufferedReader bufferedReader = 
  new BufferedReader(new InputStreamReader (process.getInputStream())); 
  while ( (line=bufferedReader.readLine()) != null){ 
  if(line.indexOf("Physical Address. . . . . . . . . :") != -1){ 
  if(line.indexOf(":") != -1){ 
  physicalAddress = line.substring(line.indexOf(":")+2); 
  :

在上面的程序中,為了讀取命令輸出的字符,利用子進程process生成了一個數據流緩沖區。

  依據上面的代碼,我們編寫了一個類ReadMac,見下面程序的源代碼:

以下是引用片段:
import Java.io.*; 
  public class ReadMac { 
  public static String physicalAddress = "read Mac error!"; 
  public ReadMac() { 
  } 
  public static String checkPhysicalAddress(){ 
  try{ 
  String line; 
  Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all"); 
  BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); 
  while ( (line=bufferedReader.readLine()) != null){ 
  if(line.indexOf("Physical Address. . . . . . . . . :") != -1){ 
  if(line.indexOf(":") != -1){ 
  physicalAddress = line.substring(line.indexOf(":")+2); 
  break; //找到Mac,推出循環 
  } 
  } 
  } 
  process.waitFor(); 
  }catch(Exception e){ 
  e.printStackTrace(); 
  } 
  return physicalAddress; 
  } 
  public static void main(String[] args) { 
  System.out.println("本機的MAC地址是: "+ ReadMac.checkPhysicalAddress()); 
  } 
  }

  編譯運行該程序的輸出結果如圖2所示。

  圖2

  由於每一台計算機的Mac地址都不同,所以該程序在不同計算機上運行結果都會不一樣。

  5 結束語

  作為一個跨平台語言,編寫的Java程序一般都與硬件無關,因而能運行在不同的操作系統環境。但這給編寫底層相關的程序時帶來不便。

  Java的應用程序都存在著一個與其運行環境相聯系的Runtime對象,利用該對象可執行外部命令,在WindowsXP/NT/2000環境中的命令IPCONFIG的輸出包含有Mac地址。本文編寫的Java程序,執行外部命令IPCONFIG,並通過分析該命令的輸入流而獲得本機的Mac地址。由於IPCONFIG命令是操作系統命令,所以該方法既方便又可靠。

  以上討論的程序適合於Windows XP/NT/2000操作系統,因為它是基於該操作系統的命令IPCONFIG格式的。由於不同操作系統讀取Mac地址的命令、以及命令輸出格式的不同,所以該程序不能直接運用到其它系統。要移植到其它系統只需針對命令的輸出格式稍作修改。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved