在 Java 中获取系统正常运行时间

问题描述 投票:0回答:6

如何确定计算机已开机多长时间(以毫秒为单位)?

java system
6个回答
14
投票

在 Windows 中,您可以执行

net stats srv
命令,在 Unix 中,您可以执行
uptime
命令。 必须解析每个输出以获得正常运行时间。 该方法通过检测用户的操作系统自动执行必要的命令。

请注意,这两个操作都不会以毫秒精度返回正常运行时间。

public static long getSystemUptime() throws Exception {
    long uptime = -1;
    String os = System.getProperty("os.name").toLowerCase();
    if (os.contains("win")) {
        Process uptimeProc = Runtime.getRuntime().exec("net stats srv");
        BufferedReader in = new BufferedReader(new InputStreamReader(uptimeProc.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            if (line.startsWith("Statistics since")) {
                SimpleDateFormat format = new SimpleDateFormat("'Statistics since' MM/dd/yyyy hh:mm:ss a");
                Date boottime = format.parse(line);
                uptime = System.currentTimeMillis() - boottime.getTime();
                break;
            }
        }
    } else if (os.contains("mac") || os.contains("nix") || os.contains("nux") || os.contains("aix")) {
        Process uptimeProc = Runtime.getRuntime().exec("uptime");
        BufferedReader in = new BufferedReader(new InputStreamReader(uptimeProc.getInputStream()));
        String line = in.readLine();
        if (line != null) {
            Pattern parse = Pattern.compile("((\\d+) days,)? (\\d+):(\\d+)");
            Matcher matcher = parse.matcher(line);
            if (matcher.find()) {
                String _days = matcher.group(2);
                String _hours = matcher.group(3);
                String _minutes = matcher.group(4);
                int days = _days != null ? Integer.parseInt(_days) : 0;
                int hours = _hours != null ? Integer.parseInt(_hours) : 0;
                int minutes = _minutes != null ? Integer.parseInt(_minutes) : 0;
                uptime = (minutes * 60000) + (hours * 60000 * 60) + (days * 6000 * 60 * 24);
            }
        }
    }
    return uptime;
}

9
投票

使用适用于 Windows、Linux 和 Mac OS 的 OSHI 库

new SystemInfo().getOperatingSystem().getSystemUptime()

3
投票

您可以使用 OSHI 库。这是示例代码

System.out.println("Uptime: "+FormatUtil.formatElapsedSecs(new oshi.SystemInfo().getOperatingSystem().getSystemUptime()));

为了使其正常工作,需要添加以下依赖项。

<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>4.0.0</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>5.4.0</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.4.0</version>
</dependency>

3
投票

我真的想不出一种不依赖操作系统的方法来做到这一点。 一个选择是使用

ManagementFactory.getRuntimeMXBean().getUptime();

这会返回您的 JVM 正常运行时间(以毫秒为单位),因此不完全是您正在寻找的内容,但已经朝着正确的方向迈出了一步。

您到底想用这些数据实现什么目的?


2
投票

对于 Windows,您可以通过查询

uptime
 获得 
windows WMI

毫秒精度

要运行以下代码,您需要下载 Jawin 库并将

jawin.dll
添加到 Eclipse 项目根目录

 public static void main(String[] args) throws COMException {
    String computerName = "";
    String userName = "";
    String password = "";
    String namespace = "root/cimv2";

    String queryProcessor = "SELECT * FROM Win32_OperatingSystem";

    DispatchPtr dispatcher = null;

    try {

        ISWbemLocator locator = new ISWbemLocator(
                "WbemScripting.SWbemLocator");
        ISWbemServices wbemServices = locator.ConnectServer(computerName,
                namespace, userName, password, "", "", 0, dispatcher);
        ISWbemObjectSet wbemObjectSet = wbemServices.ExecQuery(
                queryProcessor, "WQL", 0, null);
        DispatchPtr[] results = new DispatchPtr[wbemObjectSet.getCount()];
        IUnknown unknown = wbemObjectSet.get_NewEnum();
        IEnumVariant enumVariant = (IEnumVariant) unknown
                .queryInterface(IEnumVariant.class);

        enumVariant.Next(wbemObjectSet.getCount(), results);

        for (int i = 0; i < results.length; i++) {
            ISWbemObject wbemObject = (ISWbemObject) results[i]
                    .queryInterface(ISWbemObject.class);

            System.out.println("Uptime: "
                    + wbemObject.get("LastBootUpTime"));
        }
    } catch (COMException e) {
        e.printStackTrace();
    }

1
投票

我想要没有库的解决方案,而使用 WMIC 最适合我。

private DateTime getSystemBootTime() throws IOException {
    String os = System.getProperty("os.name").toLowerCase();
    if (os.contains("win")) {
        Process uptimeProc = Runtime.getRuntime().exec("WMIC os get lastbootuptime");
        BufferedReader in = new BufferedReader(new InputStreamReader(uptimeProc.getInputStream()));
        String line = "";
        while ((line = in.readLine()) != null) {
            if (line.startsWith("ERROR")) {
                logger.error("CheckMachineUptime failed. WMIC operation failed. MACHINE OS: {} CMD output: {}", os, line);
                break;
            }
            if (line.startsWith("2")) {
                SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
                try {
                    return new DateTime(format.parse(line));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        logger.error("Task failed! Could not identify time format. CMD OUTPUT: {}", in.readLine());
    } else logger.error("Task failed! Could not identify machine OS. MACHINE OS: {}", os);
    throw new RuntimeException("Getting uptime failed");
}

感谢 FThompson 和本帖子中的评论者。

© www.soinside.com 2019 - 2024. All rights reserved.