596

我想确定我的 Java 程序正在以编程方式运行的主机的操作系统(例如:我希望能够根据我是在 Windows 还是 Unix 平台上加载不同的属性)。100% 可靠的最安全方法是什么?

4

21 回答 21

705

您可以使用:

System.getProperty("os.name")

PS您可能会发现此代码很有用:

class ShowProperties {
    public static void main(String[] args) {
        System.getProperties().list(System.out);
    }
}

它所做的只是打印出 Java 实现提供的所有属性。它将让您了解通过属性可以找到有关 Java 环境的信息。:-)

于 2008-10-23T03:48:47.127 回答
183

如其他答案所示, System.getProperty 提供原始数据。但是,Apache Commons Lang 组件为 java.lang.System提供了一个包装器,该包装器具有方便的属性,例如SystemUtils.IS_OS_WINDOWS,很像前面提到的 Swingx OS 实用程序。

于 2010-05-27T00:17:12.847 回答
98

2008 年 10 月:

我建议将其缓存在静态变量中:

public static final class OsUtils
{
   private static String OS = null;
   public static String getOsName()
   {
      if(OS == null) { OS = System.getProperty("os.name"); }
      return OS;
   }
   public static boolean isWindows()
   {
      return getOsName().startsWith("Windows");
   }

   public static boolean isUnix() // and so on
}

这样,每次您请求 Os 时,您不会在应用程序的生命周期内多次获取该属性。


2016 年 2 月:7 年后:

Windows 10 存在一个错误(在原始答案时不存在)。
请参阅“适用于 Windows 10 的 Java 的“os.name”?

于 2008-10-23T03:58:33.830 回答
54

上面答案中的某些链接似乎已损坏。我在下面的代码中添加了指向当前源代码的指针,并提供了一种使用枚举作为答案来处理检查的方法,以便在评估结果时可以使用 switch 语句:

OsCheck.OSType ostype=OsCheck.getOperatingSystemType();
switch (ostype) {
    case Windows: break;
    case MacOS: break;
    case Linux: break;
    case Other: break;
}

助手类是:

/**
 * helper class to check the operating system this Java VM runs in
 *
 * please keep the notes below as a pseudo-license
 *
 * http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java
 * compare to http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/Os.java
 * http://www.docjar.com/html/api/org/apache/commons/lang/SystemUtils.java.html
 */
import java.util.Locale;
public static final class OsCheck {
  /**
   * types of Operating Systems
   */
  public enum OSType {
    Windows, MacOS, Linux, Other
  };

  // cached result of OS detection
  protected static OSType detectedOS;

  /**
   * detect the operating system from the os.name System property and cache
   * the result
   * 
   * @returns - the operating system detected
   */
  public static OSType getOperatingSystemType() {
    if (detectedOS == null) {
      String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
      if ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)) {
        detectedOS = OSType.MacOS;
      } else if (OS.indexOf("win") >= 0) {
        detectedOS = OSType.Windows;
      } else if (OS.indexOf("nux") >= 0) {
        detectedOS = OSType.Linux;
      } else {
        detectedOS = OSType.Other;
      }
    }
    return detectedOS;
  }
}
于 2013-08-24T10:09:31.067 回答
47

以下 JavaFX 类具有确定当前操作系统的静态方法(isWindows()、isLinux()...):

  • com.sun.javafx.PlatformUtil
  • com.sun.media.jfxmediaimpl.HostUtils
  • com.sun.javafx.util.Utils

例子:

if (PlatformUtil.isWindows()){
           ...
}
于 2016-12-15T22:32:53.937 回答
33

TL;博士

访问操作系统使用:System.getProperty("os.name").


可是等等!!!

为什么不创建一个实用程序类,让它可重用!并且在多次通话时可能要快得多。干净,清晰,更快!

为此类实用程序函数创建一个 Util 类。然后为每种操作系统类型创建公共枚举。

public class Util {     
        public enum OS {
            WINDOWS, LINUX, MAC, SOLARIS
        };// Operating systems.

    private static OS os = null;

    public static OS getOS() {
        if (os == null) {
            String operSys = System.getProperty("os.name").toLowerCase();
            if (operSys.contains("win")) {
                os = OS.WINDOWS;
            } else if (operSys.contains("nix") || operSys.contains("nux")
                    || operSys.contains("aix")) {
                os = OS.LINUX;
            } else if (operSys.contains("mac")) {
                os = OS.MAC;
            } else if (operSys.contains("sunos")) {
                os = OS.SOLARIS;
            }
        }
        return os;
    }
}

现在,您可以轻松地从任何类中调用类,如下所示,(PS 由于我们将 os 变量声明为静态,它只会消耗一次时间来识别系统类型,然后可以使用它直到您的应用程序停止。)

            switch (Util.getOS()) {
            case WINDOWS:
                //do windows stuff
                break;
            case LINUX:

就是这样!

于 2015-07-21T19:02:48.163 回答
18

您尝试实现的一个小例子可能class与下面的类似:

import java.util.Locale;

public class OperatingSystem
{
    private static String OS = System.getProperty("os.name", "unknown").toLowerCase(Locale.ROOT);

    public static boolean isWindows()
    {
        return OS.contains("win");
    }

    public static boolean isMac()
    {
        return OS.contains("mac");
    }

    public static boolean isUnix()
    {
        return OS.contains("nux");
    }
}

这个特定的实现是非常可靠的,应该是普遍适用的。只需将其复制并粘贴到您class选择的位置即可。

于 2013-07-06T19:06:32.490 回答
11

试试这个,简单易行

System.getProperty("os.name");
System.getProperty("os.version");
System.getProperty("os.arch");
于 2014-05-07T08:20:57.057 回答
10

如果你对开源项目如何做这样的事情感兴趣,你可以在这里查看处理这些垃圾的 Terracotta 类 (Os.java):

您可以在这里看到一个类似的类来处理 JVM 版本(Vm.java 和 VmVersion.java):

于 2008-10-23T04:37:26.543 回答
8

下面的代码显示了您可以从 System API 获得的值,这些都是您可以通过此 API 获得的所有内容。

public class App {
    public static void main( String[] args ) {
        //Operating system name
        System.out.println(System.getProperty("os.name"));

        //Operating system version
        System.out.println(System.getProperty("os.version"));

        //Path separator character used in java.class.path
        System.out.println(System.getProperty("path.separator"));

        //User working directory
        System.out.println(System.getProperty("user.dir"));

        //User home directory
        System.out.println(System.getProperty("user.home"));

        //User account name
        System.out.println(System.getProperty("user.name"));

        //Operating system architecture
        System.out.println(System.getProperty("os.arch"));

        //Sequence used by operating system to separate lines in text files
        System.out.println(System.getProperty("line.separator"));

        System.out.println(System.getProperty("java.version")); //JRE version number

        System.out.println(System.getProperty("java.vendor.url")); //JRE vendor URL

        System.out.println(System.getProperty("java.vendor")); //JRE vendor name

        System.out.println(System.getProperty("java.home")); //Installation directory for Java Runtime Environment (JRE)

        System.out.println(System.getProperty("java.class.path"));

        System.out.println(System.getProperty("file.separator"));
    }
}

答案:-

Windows 7
6.1
;
C:\Users\user\Documents\workspace-eclipse\JavaExample
C:\Users\user
user
amd64


1.7.0_71
http://java.oracle.com/
Oracle Corporation
C:\Program Files\Java\jre7
C:\Users\user\Documents\workspace-Eclipse\JavaExample\target\classes
\
于 2015-05-03T09:51:12.540 回答
8

我认为以下可以在更少的行中提供更广泛的覆盖范围

import org.apache.commons.exec.OS;

if (OS.isFamilyWindows()){
                //load some property
            }
else if (OS.isFamilyUnix()){
                //load some other property
            }

更多细节在这里:https ://commons.apache.org/proper/commons-exec/apidocs/org/apache/commons/exec/OS.html

于 2018-09-27T07:36:18.140 回答
8

如果您在安全敏感的环境中工作,请通读此内容。

请不要相信通过System#getProperty(String)子程序获得的属性!os.arch实际上,包括、os.name和在内的几乎所有属性os.version都不是你所期望的 readonly ——相反,它们实际上完全相反。

首先,任何有足够权限调用System#setProperty(String, String)子程序的代码都可以随意修改返回的字面量。但是,这不一定是这里的主要问题,因为它可以通过使用所谓的 来解决SecurityManager,正如在此处更详细地描述的那样。

实际问题是任何用户在运行有JAR问题的程序时都可以编辑这些属性(通过-Dos.name=-Dos.arch=等)。避免篡改应用程序参数的一种可能方法是查询此处RuntimeMXBean所示的。下面的代码片段应该提供一些关于如何实现这一点的见解。

RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();

for (String argument : arguments) {
    if (argument.startsWith("-Dos.name") {
        // System.getProperty("os.name") altered
    } else if (argument.startsWith("-Dos.arch") {
        // System.getProperty("os.arch") altered
    }
}
于 2019-08-22T20:22:04.437 回答
6

我发现Swingx 的 OS Utils 可以完成这项工作。

于 2008-10-23T04:40:21.717 回答
5
String osName = System.getProperty("os.name");
System.out.println("Operating system " + osName);
于 2013-04-29T12:36:26.783 回答
3

我喜欢沃尔夫冈的回答,只是因为我相信这样的事情应该是 consts ......

所以我为自己改写了一下,并想分享它:)

/**
 * types of Operating Systems
 *
 * please keep the note below as a pseudo-license
 *
 * helper class to check the operating system this Java VM runs in
 * http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java
 * compare to http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/Os.java
 * http://www.docjar.com/html/api/org/apache/commons/lang/SystemUtils.java.html
 */
public enum OSType {
    MacOS("mac", "darwin"),
    Windows("win"),
    Linux("nux"),
    Other("generic");

    private static OSType detectedOS;

    private final String[] keys;

    private OSType(String... keys) {
        this.keys = keys;
    }

    private boolean match(String osKey) {
        for (int i = 0; i < keys.length; i++) {
            if (osKey.indexOf(keys[i]) != -1)
                return true;
        }
        return false;
    }

    public static OSType getOS_Type() {
        if (detectedOS == null)
            detectedOS = getOperatingSystemType(System.getProperty("os.name", Other.keys[0]).toLowerCase());
        return detectedOS;
    }

    private static OSType getOperatingSystemType(String osKey) {
        for (OSType osType : values()) {
            if (osType.match(osKey))
                return osType;
        }
        return Other;
    }
}
于 2014-03-17T11:38:50.573 回答
3

您可以只使用 sun.awt.OSInfo#getOSType() 方法

于 2016-01-22T15:46:18.253 回答
3

顶级答案的更短,更清晰(并且急切地计算)的版本:

switch(OSType.DETECTED){
...
}

辅助枚举:

public enum OSType {
    Windows, MacOS, Linux, Other;
    public static final  OSType DETECTED;
    static{
        String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
        if ((OS.contains("mac")) || (OS.contains("darwin"))) {
            DETECTED = OSType.MacOS;
        } else if (OS.contains("win")) {
            DETECTED = OSType.Windows;
        } else if (OS.contains("nux")) {
            DETECTED = OSType.Linux;
        } else {
            DETECTED = OSType.Other;
        }
    }
}
于 2021-06-06T23:25:46.760 回答
2

此代码用于显示有关系统操作系统类型、名称、java 信息​​等的所有信息。

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Properties pro = System.getProperties();
    for(Object obj : pro.keySet()){
        System.out.println(" System  "+(String)obj+"     :  "+System.getProperty((String)obj));
    }
}
于 2014-08-01T10:47:27.327 回答
0

在 com.sun.jna.Platform 类中,您可以找到有用的静态方法,例如

Platform.isWindows();
Platform.is64Bit();
Platform.isIntel();
Platform.isARM();

以及更多。

如果您使用 Maven 只需添加依赖项

<dependency>
 <groupId>net.java.dev.jna</groupId>
 <artifactId>jna</artifactId>
 <version>5.2.0</version>
</dependency>

否则只需找到 j​​na 库 jar 文件(例如 jna-5.2.0.jar)并将其添加到类路径中。

于 2019-05-15T05:48:41.900 回答
0

只需com.sun.javafx.util.Utils如下使用。

if ( Utils.isWindows()){
     // LOGIC HERE
}

或使用

boolean isWindows = OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS);
       if (isWindows){
         // YOUR LOGIC HERE
       }
于 2019-07-03T11:43:05.957 回答
0

由于谷歌将“kotlin os name”指向此页面,因此这是@Memin答案的 Kotlin 版本:

private var _osType: OsTypes? = null
val osType: OsTypes
    get() {
        if (_osType == null) {
            _osType = with(System.getProperty("os.name").lowercase(Locale.getDefault())) {
                if (contains("win"))
                    OsTypes.WINDOWS
                else if (listOf("nix", "nux", "aix").any { contains(it) })
                    OsTypes.LINUX
                else if (contains("mac"))
                    OsTypes.MAC
                else if (contains("sunos"))
                    OsTypes.SOLARIS
                else
                    OsTypes.OTHER
            }
        }
        return _osType!!
    }

enum class OsTypes {
    WINDOWS, LINUX, MAC, SOLARIS, OTHER
}
于 2021-08-06T12:31:28.407 回答