在Java中获取计算机名称

65

我想知道在Java中是否有一种方法可以获取计算机名称?我看到了几个使用java.net.InetAddress的答案。但是我想知道是否有不使用网络的方法?

(另外一个问题,计算机名称只是一个网络事物吗,因此必须通过这种方式完成吗?)


1
尝试访问 https://dev59.com/SXRB5IYBdhLWcg3w6LR2 - Jonathan Spooner
你实际上只是在使用回环接口,也就是“localhost”。 - Jonathan Spooner
3
为不在网络中的计算机命名就像给猫起名字一样——除了它不会在你叫它的时候无动于衷外,没有人会呼唤它。 - Paul Tomblin
1
@JonathanSpooner - 嗯,我们的生产机器因此在/etc/hosts中有它们的真实名称。我不会得到“localhost”;) - Brian Roach
4
当然不行 - 你可以把它命名为5。后续的猫应该被命名为5e6 ;) (尽管我想如果你是老派的话,你可以把一个命名为TenBaseTee - Brian Roach
显示剩余6条评论
3个回答

103
计算机的“名称”是通过操作系统底层的DNS(域名系统)库从IP地址中“解析”出来的。不同操作系统之间没有通用的计算机名称概念,但通常都支持DNS。如果未配置计算机名称以便DNS解析,则该名称不可用。
import java.net.InetAddress;
import java.net.UnknownHostException;

String hostname = "Unknown";

try
{
    InetAddress addr;
    addr = InetAddress.getLocalHost();
    hostname = addr.getHostName();
}
catch (UnknownHostException ex)
{
    System.out.println("Hostname can not be resolved");
}

37
OP询问“不使用网络”的解决方案,但这个被接受的答案是怎么回事呢?我想知道。 - peterh
1
在Mac OS X上,这个解决方案可能会提供一个不同的主机名,具体取决于计算机是否连接到网络。 - Octave

66

我同意peterh的回答,所以对于那些喜欢复制粘贴而不是再花60秒钟谷歌搜索的人:

private String getComputerName()
{
    Map<String, String> env = System.getenv();
    if (env.containsKey("COMPUTERNAME"))
        return env.get("COMPUTERNAME");
    else if (env.containsKey("HOSTNAME"))
        return env.get("HOSTNAME");
    else
        return "Unknown Computer";
}

我已在Windows 7上测试过,可行。如果peterh是正确的话,else if应该能处理Mac和Linux。或许有人可以测试一下?如果你想要更高的鲁棒性,你也可以在else中实现Brian Roach的答案。


2
对于Ubuntu 14.04,至少目前这种方法行不通。唯一出现计算机名称的环境变量是SESSION_MANAGER变量。但你需要解析它,因为它看起来像这样:local/<<name>>:@/tmp/.ICE-unix/2131,unix/<<name>>:/tmp/.ICE-unix/2131 - Sharcoux
如果您发出“export HOSTNAME”命令,则环境变量将传递给子任务。 - neuhaus
Peterh在这里。感谢您的实现。关于Unix / Linux和Sharcoux的评论,我已经更新了我的答案 - peterh
作为Ubuntu的替代方案,可以捕获hostname命令的输出... - snorbi
3
我更倾向于将函数设置为“public static”。 - bct
显示剩余2条评论

55

我对互联网上和这里提供的 InetAddress.getLocalHost().getHostName() 解决方案并不是很满意。该方法将获取从网络视角看到的主机名。我认为有两个问题:

  1. 如果主机有多个网络接口怎么办?主机可能有多个名称出现在网络中。据我所知,该方法返回的名称是不确定的。

  2. 如果主机没有连接到任何网络且没有网络接口怎么办?

我知道的所有操作系统都有一个将节点/主机命名的概念,无论是否与网络相连。Java不能以一种简单的方式返回这一点,令人遗憾。在所有版本的Windows上,这将是环境变量 COMPUTERNAME,在Unix / Linux / MacOS上,这将是环境变量 HOSTNAME(或者是来自 host 命令的输出 hostname,如果HOSTNAME 环境变量不可用,如 Bourne 和 Korn 等旧 shell 的情况下)。

我会编写一个方法,该方法将检索(取决于操作系统)这些操作系统变量,并仅在最后使用 InetAddress.getLocalHost().getHostName() 方法作为最后手段。但这只是我的想法。

更新(Unix)

正如其他人指出的那样,对于 Unix / Linux 上的 Java 应用程序,HOSTNAME 环境变量通常不可用,因为默认情况下没有导出。除非您控制客户端,否则这不是一个可靠的方法。这真的很糟糕。为什么没有一种带有这些信息的标准属性呢?

唯一可靠的Unix/Linux获取主机名的方法似乎是通过JNI调用gethostname()或使用Runtime.exec()命令来捕获hostname命令的输出。我并不喜欢这些想法,但如果有更好的想法,我非常愿意倾听。(更新:我最近发现了gethostname4j,它似乎是我的救星)

长篇阅读

我在另一个帖子中的另一个答案中提供了详细解释。特别是因为它试图建立一些术语,给出了当InetAddress.getLocalHost().getHostName()方法失效时的具体示例,并指向目前我所知道的唯一安全的解决方案,即gethostname4j

Java没有提供一种获取计算机名称的方法,这很遗憾。如果你能,请为JDK-8169296投票。


我喜欢gethostname4j解决方案!我尝试编辑/etc/hosts文件,就像其他人建议的那样。不知道为什么,但对我来说它并没有解决问题。gethostname4j返回与Inet相同的名称,但速度更快,特别是在Mac上。 - mbreck
我也很喜欢你的库!感谢您为社区开发了这样一个好的解决方案。 - Barracuda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接