【问题标题】:Get Unix hostid into Java将 Unix hostid 获取到 Java
【发布时间】:2011-09-21 14:35:42
【问题描述】:

如何通过某种调用将 unix hostid 获取到 Java 中?

http://linux.about.com/library/cmd/blcmdl1_hostid.htm

【问题讨论】:

  • 看来hostid是一个程序所以见stackoverflow.com/questions/5053766/…
  • 是的,但是您可以直接在 Java 中获得相同的信息;请参阅下面的解决方案。
  • 对于 IPv4 机器,可以读取 /etc/hostid 形式的 hostid 或从主机名的 ip 地址计算它。这样您就不必调用另一个程序来获得结果。见下文。

标签: java linux unix uniqueidentifier


【解决方案1】:

恐怕您将不得不编写 JNI(或 JNA)。

【讨论】:

  • 或者使用Runtime,甚至作为参数传递
  • 是的。如果这是针对我控制的内部系统,我可以使用 exec()ing。但如果这是我要发布的应用程序,那么我会使用 JNI,因为我只知道客户对他们糟糕的机器做了什么。
【解决方案2】:

也许下面的文章会有所帮助。

http://www.devdaily.com/java/java-exec-processbuilder-process-1

【讨论】:

    【解决方案3】:

    调用Runtime.exec(String),其中参数是“hostid”可执行文件的路径,然后排出结果Process object 的两个流,并将标准输出流的内容作为字符串值。

    这个简单的类演示了如何实现此策略(但需要改进错误处理 [例如 stderr、异常] 和 OOP 最佳实践 [例如返回具有 bean 属性的对象等]):

    public class RunCommand {
      public static String exec(String command) throws Exception {
        Process p = Runtime.getRuntime().exec(command);
        String stdout = drain(p.getInputStream());
        String stderr = drain(p.getErrorStream());
        return stdout; // TODO: return stderr also...
      }
      private static String drain(InputStream in) throws IOException {
        int b = -1;
        StringBuilder buf = new StringBuilder();
        while ((b=in.read()) != -1) buf.append((char) b);
        return buf.toString();
      }
    }
    

    你的程序可以这样使用它:

    String myHostId = RunCommand.exec("/usr/bin/hostid").trim();
    

    请注意,如果您的命令需要参数或环境等,使用ProcessBuilder 创建Process 可能比Runtime.exec() 更合适。

    【讨论】:

      【解决方案4】:

      试试这个(当然包含在某个类中):

      import java.net.InetAddress;
      import java.net.UnknownHostException;
      
      public static String getLocalHostIP()
          throws UnknownHostException
      {
          InetAddress  ip;
      
          ip = InetAddress.getLocalHost();
          return ip.getHostAddress();
      }
      

      该方法返回“xxx.xxx.xxx.xxx”形式的字符串。

      更新

      一种改进的方法是:

      // Determine the IP address of the local host
      public static String getLocalHostIP()
      {
          try
          {
              return InetAddress.getLocalHost().getHostAddress();
          }
          catch (UnknownHostException ex)
          {
              return null;
          }
      }
      

      【讨论】:

      • hostid 不是 IP 地址。
      • @Edward:好吧,那么,不管了。
      • @Edward,实际上我已经阅读了 Linux 上 hostid 的 glibc 实现,它是 IP 地址,转换为 32 位无符号整数,低 16 位和高 16 位交换。这就是为什么我编写了上面截取的代码,它返回的 hostid 值与 hostid 程序(在我的系统上)完全相同。
      • @Edwin - 我同意,但信息页面不能保证未来不会改变实施。此外,可以使用 sethostid(3) 修改此值。如果这严格适用于您控制的机器,那么我同意实施者会知道这是否是合适的解决方案。但是,如果您确实需要 hostid 的值,我认为您实际上需要调用 gethostid(3) (或执行一个执行相同操作的程序。)
      • @Edward,更改实现是可能的,但这意味着在为 POSIX 合规性提供的函数中更新 glibc。是的,它可能会发生,但如果他们在 30 年内想出的最好的结果是一个带有一些字节交换的 IP 地址,我不会屏住呼吸。
      【解决方案5】:

      如果它是由先前对sethostid(long int id) 的调用设置的,它将驻留在HOSTIDFILE,通常是/etc/hostid

      如果不存在,则获取机器的主机名。您提取主机名的地址,如果是 IPv4,它是从点分十进制格式到二进制格式的 IPv4 地址,前 16 位和低 16 位交换。

      InetAddress addr = InetAddress.getLocalHost();
      byte[] ipaddr = addr.getAddress();
      if (ipaddr.length == 4) {
        int hostid = 0 | ipaddr[1] << 24 | ipaddr[0] << 16 | ipaddr[3] << 8 | ipaddr[2];
        StringBuilder sb = new StringBuilder();
        Formatter formatter = new Formatter(sb, Locale.US);
        formatter.format("%08x", hostid);
        System.out.println(sb.toString());
      } else {
        throw new Exception("hostid for IPv6 addresses not implemented yet");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-21
        • 2016-06-15
        • 1970-01-01
        • 2011-05-17
        • 2015-01-19
        • 1970-01-01
        • 2018-01-05
        相关资源
        最近更新 更多