Javaで MACアドレスを抽出する

java.net.NetworkInterface を利用して抽出します。
NetworkInterface から、getHardwareAddress() で、ハードウエアのアドレス=MAC アドレスに相当が見れます。

NetworkInterface は、以下の static メソッドがあります。

getByIndex(int index)               → 指定インデックスのネットワークインターフェース
getByInetAddress(InetAddress addr) → 指定IPアドレスのネットワークインターフェース
getByName(String name) → 指定する名前のネットワークインターフェース
getNetworkInterfaces() → 実行マシン上のすべてのネットワークインターフェース

だいたい、getNetworkInterfaces か、getByInetAddress を使用するのが実践向きと考えます。

getNetworkInterfaces が返すのは、残念ながら、Enumeration です。

getNetworkInterfaces を実行すると Windows PC の場合、
Teredo Tunneling Pseudo-Interface
  IPv6 over IPv4トンネリングプロトコルとして割り当てたものまで採取できてしまいます。
これはよくみると、6バイトで表す MACアドレスになってませんでした。


全てを見る場合、Enumeration なので、仕方なく while ループで書いてみます。

try{
   Enumeration<NetworkInterface> nfs = NetworkInterface.getNetworkInterfaces();
   while(nfs.hasMoreElements()){
      NetworkInterface nf = nfs.nextElement();

      String address = Optional.ofNullable(nf.getHardwareAddress())
      .map(e->IntStream.range(0, e.length).mapToObj(i->String.format("%02X", e[i]))
               .collect(Collectors.joining(" ")))
      .orElse(null);

      System.out.printf("%d,%d,%s,\"%s\",%s%n"
         , nf.isLoopback() ? 1 : 0
         , nf.isUp() ? 1 : 0
         , nf.getName()
         , nf.getDisplayName()
         , address
      );
   }
}catch(SocketException ex){
   ex.printStackTrace();
}

NetworkInterface の isUp()メソッドが返す動作してるものだけ抽出は、これだとwhile文中にif文書かなければ
なりません。

isUp()メソッドをつかうものを単純に Stream で書いてみます。

try{
   Collections.list(NetworkInterface.getNetworkInterfaces())
   .stream().filter(n->{
      try{
         return n.isUp();
      }catch(SocketException e){
      }
      return false;
   }).forEach(nf->{
      try{
         String address = Optional.ofNullable(nf.getHardwareAddress())
            .map(e->IntStream.range(0, e.length)
                     .mapToObj(i->String.format("%02X", e[i])).collect(Collectors.joining(" ")))
            .orElse(null);
         System.out.printf("%d,%d,%s,\"%s\",%s%n"
            , nf.isLoopback() ? 1 : 0
            , nf.isUp() ? 1 : 0
            , nf.getName()
            , nf.getDisplayName()
            , address
         );
      }catch(SocketException ex){
         ex.printStackTrace();
      }
   });
}catch(SocketException ex){
   ex.printStackTrace();
}

ラムダの中に try~catch を書くハメになってみっともない。Predicate や Consumer の例外スローするものでも
用意するか。。。

getByInetAddress で1つの MACアドレスを抽出する場合、、、

try{
   NetworkInterface nf = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());

   String address = Optional.ofNullable(nf.getHardwareAddress())
         .map(e->IntStream.range(0, e.length).mapToObj(i->String.format("%02X", e[i]))
                  .collect(Collectors.joining(" ")))
         .orElse(null);

   System.out.printf("%d,%d,%s,\"%s\",%s%n"
      , nf.isLoopback() ? 1 : 0
      , nf.isUp() ? 1 : 0
      , nf.getName()
      , nf.getDisplayName()
      , address
   );

}catch(SocketException ex){
   ex.printStackTrace();
}catch(UnknownHostException ex){
   ex.printStackTrace();
}

InetAddress.getLocalHost() の実行で、UnknownHostException 捕捉も必要になります。