【发布时间】:2011-05-17 16:19:01
【问题描述】:
我正在尝试找出运行应用程序的本地机器的名称(或其他唯一标识特定机器的方法)。
我一直在用这个:
String hostname = java.net.InetAddress.getLocalHost().getHostName();
这很好用,但我只是碰巧在分析器中注意到执行它需要相当长的时间,所以我想知道是否有一些功能相似的东西运行得更快。
不必是主机名,可以是任何东西,只要它唯一地标识机器即可。
【问题讨论】:
我正在尝试找出运行应用程序的本地机器的名称(或其他唯一标识特定机器的方法)。
我一直在用这个:
String hostname = java.net.InetAddress.getLocalHost().getHostName();
这很好用,但我只是碰巧在分析器中注意到执行它需要相当长的时间,所以我想知道是否有一些功能相似的东西运行得更快。
不必是主机名,可以是任何东西,只要它唯一地标识机器即可。
【问题讨论】:
为了唯一标识一台机器,我将使用系统 MAC 地址getHardwareAddress()。
但是,我不确定这是否会更快 - 但它肯定是唯一识别机器的更好方法。
【讨论】:
您可以获取机器的 MAC 地址。这是一个如何获取它的示例。
byte[] mac = null;
List<NetworkInterface> interfaces =
(List<NetworkInterface>) Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface iface: interfaces) {
if (!iface.isLoopback()) {
mac = iface.getHardwareAddress();
if (mac != null) {
break;
}
}
}
此代码从第一个具有 MAC 地址的接口中获取 MAC 地址。除了环回接口之外,某些机器可能还具有用于 VPN 的虚拟接口,这些接口没有与之关联的硬件地址。
【讨论】:
试过getHostAddress()?从文档来看,getHostName() 似乎首先涉及安全检查(如果有SecurityManager),这意味着要再调用一个方法。
【讨论】:
我想出了这个:
String dirname = Utils.safetrim(System.getProperty("user.dir"));
它显然不能唯一地识别一台机器,但对我来说它已经足够好了,因为每个运行这个程序的人都将以自己的身份登录,并且可能从他们的主目录运行,所以它使响应足够独特我。
当然它的速度很快,这是重要的部分。
【讨论】:
只是为了避免下一个人因不完整的 MAC 检索代码而绊倒,这是我的版本,适用于我的 Windows 7 机器以及其他计算机。请注意,代码可能仍会在每次调用时返回不同的 MAC,以防用户弄乱了他的硬件并且网络设备可能以不同的顺序返回。
private static final String generateHashIdentifier() throws Exception {
Enumeration<NetworkInterface> networkInterfaces
= NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
if (networkInterface == null
|| networkInterface.isLoopback()
|| networkInterface.isVirtual()) {
continue;
}
byte[] mac = networkInterface.getHardwareAddress();
if (mac == null || mac.length == 0)
continue;
StringBuilder sb = new StringBuilder();
int zeroFieldCount = 0;
for (int i = 0; i < mac.length; i++) {
if (mac[i] == 0)
zeroFieldCount++;
sb.append(String.format("%02X%s", mac[i],
(i < mac.length - 1) ? "-" : ""));
}
if (zeroFieldCount > 4)
continue;
return sb.toString();
}
throw new RuntimeException("Failed to obtain MAC");
}
在 Windows 中,我得到了大量的附加设备,它们可能返回也可能不返回 NULL mac 或大部分为零的 mac。代码试图找到第一个给出合理 MAC 的设备,并将它作为一个不错的字符串返回。
【讨论】: