下面哪一种方法是在Java中获得当前计算机主机名的最佳和最可移植的方法?

Runtime.getRuntime().exec(“hostname”)

vs

InetAddress.getLocalHost().getHostName()


当前回答

在Java中获取当前计算机主机名的最方便的方法如下:

import java.net.InetAddress;
import java.net.UnknownHostException;

public class getHostName {

    public static void main(String[] args) throws UnknownHostException {
        InetAddress iAddress = InetAddress.getLocalHost();
        String hostName = iAddress.getHostName();
        //To get  the Canonical host name
        String canonicalHostName = iAddress.getCanonicalHostName();

        System.out.println("HostName:" + hostName);
        System.out.println("Canonical Host Name:" + canonicalHostName);
    }
}

其他回答

环境变量也可以提供有用的方法——Windows上的COMPUTERNAME,大多数现代Unix/Linux shell上的HOSTNAME。

参见:https://stackoverflow.com/a/17956000/768795

我使用这些作为InetAddress.getLocalHost(). gethostname()的“补充”方法,因为正如一些人指出的那样,该函数不能在所有环境中工作。

Runtime.getRuntime().exec("hostname")是另一个可能的补充。在这个阶段,我还没有用过它。

import java.net.InetAddress;
import java.net.UnknownHostException;

// try InetAddress.LocalHost first;
//      NOTE -- InetAddress.getLocalHost().getHostName() will not work in certain environments.
try {
    String result = InetAddress.getLocalHost().getHostName();
    if (StringUtils.isNotEmpty( result))
        return result;
} catch (UnknownHostException e) {
    // failed;  try alternate means.
}

// try environment properties.
//      
String host = System.getenv("COMPUTERNAME");
if (host != null)
    return host;
host = System.getenv("HOSTNAME");
if (host != null)
    return host;

// undetermined.
return null;

正如其他人所指出的,根据DNS解析获取主机名是不可靠的。

不幸的是,由于这个问题在2018年仍然相关,我想与大家分享我的网络独立解决方案,并在不同的系统上进行一些测试。

下面的代码尝试执行以下操作:

在Windows上 通过System.getenv()读取环境变量COMPUTERNAME。 执行hostname.exe并读取响应 在Linux上 通过System.getenv()读取HOSTNAME环境变量 执行主机名并读取响应 读取/etc/hostname(要做到这一点,我执行cat,因为代码段已经包含要执行和读取的代码。不过,简单地阅读文件会更好)。

代码:

public static void main(String[] args) throws IOException {
    String os = System.getProperty("os.name").toLowerCase();

    if (os.contains("win")) {
        System.out.println("Windows computer name through env:\"" + System.getenv("COMPUTERNAME") + "\"");
        System.out.println("Windows computer name through exec:\"" + execReadToString("hostname") + "\"");
    } else if (os.contains("nix") || os.contains("nux") || os.contains("mac os x")) {
        System.out.println("Unix-like computer name through env:\"" + System.getenv("HOSTNAME") + "\"");
        System.out.println("Unix-like computer name through exec:\"" + execReadToString("hostname") + "\"");
        System.out.println("Unix-like computer name through /etc/hostname:\"" + execReadToString("cat /etc/hostname") + "\"");
    }
}

public static String execReadToString(String execCommand) throws IOException {
    try (Scanner s = new Scanner(Runtime.getRuntime().exec(execCommand).getInputStream()).useDelimiter("\\A")) {
        return s.hasNext() ? s.next() : "";
    }
}

不同操作系统的结果:

macOS 10 .13.2

Unix-like computer name through env:"null"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:""

OpenSuse 13.1

Unix-like computer name through env:"machinename"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:""

Ubuntu 14.04 LTS 这个有点奇怪,因为echo $HOSTNAME返回正确的主机名,但是System.getenv("HOSTNAME")没有:

Unix-like computer name through env:"null"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:"machinename
"

编辑:根据legolas108, System.getenv("HOSTNAME")在Ubuntu 14.04上工作,如果你在执行Java代码之前运行export HOSTNAME。

Windows 7

Windows computer name through env:"MACHINENAME"
Windows computer name through exec:"machinename
"

Windows 10

Windows computer name through env:"MACHINENAME"
Windows computer name through exec:"machinename
"

机器名称已被替换,但我保留了大写和结构。注意在执行主机名时额外的换行符,在某些情况下可能必须考虑到它。

如果您不反对使用来自maven中心的外部依赖,我编写了gethostname4j来为自己解决这个问题。它只是使用JNA来调用libc的gethostname函数(或在Windows上获取ComputerName)并将其作为字符串返回给您。

https://github.com/mattsheppard/gethostname4j

InetAddress.getLocalHost(). gethostname()是更可移植的方式。

Exec(“hostname”)实际上调用操作系统来执行hostname命令。

以下是关于SO的一些其他相关答案:

Java当前机器名和登录用户? 获取本地机器的DNS名称,就像远程机器看到的那样

编辑:你应该看看A.H.的回答,或者Arnout Engelen的回答,详细说明为什么这可能不会像预期的那样工作,这取决于你的情况。作为对这个特别要求可移植的人的回答,我仍然认为getHostName()很好,但它们提出了一些值得考虑的优点。

InetAddress.getLocalHost().getHostName()是更好的(由Nick解释),但仍然不是很好

一个主机可以使用许多不同的主机名。通常,您将在特定的上下文中查找主机名。

例如,在web应用程序中,您可能要查找发出您当前正在处理的请求的人所使用的主机名。如何最好地找到它取决于你的web应用程序使用的框架。

在其他一些面向互联网的服务中,你会希望你的服务从“外部”可用的主机名。由于代理、防火墙等原因,这甚至可能不是安装服务的机器上的主机名——你可能会尝试提出一个合理的默认值,但你一定要让安装它的人都可以配置它。