Как программно определить операционную систему на Java?

Я хотел бы определить операционную систему хоста, на котором моя Java-программа выполняется программно (например: я хотел бы иметь возможность загружать различные свойства в зависимости от того, работаю ли я на платформе Windows или Unix). Какой самый безопасный способ сделать это со 100% надежностью?

24 ответа

Решение

Ты можешь использовать:

System.getProperty("os.name")

PS Вы можете найти этот код полезным:

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

Все, что он делает, это распечатывает все свойства, предоставляемые вашими реализациями Java. Это даст вам представление о том, что вы можете узнать о вашей среде Java через свойства.:-)

Как указано в других ответах, System.getProperty предоставляет необработанные данные. Тем не менее, компонент Apache Commons Lang предоставляет оболочку для java.lang.System с удобными свойствами, такими как SystemUtils.IS_OS_WINDOWS, очень похожими на вышеупомянутую утилиту Swingx OS.

Октябрь 2008 г.:

Я бы порекомендовал кэшировать его в статической переменной:

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: 7+ лет спустя:

В Windows 10 есть ошибка (которой не было на момент первоначального ответа).
Смотрите " Java os.name" для Windows 10?"

Некоторые ссылки в ответах выше не работают. Я добавил указатели к текущему исходному коду в приведенном ниже коде и предлагаю подход для обработки проверки с помощью перечисления в качестве ответа, чтобы можно было использовать оператор 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://stackru.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;
  }
}

Следующие классы JavaFX имеют статические методы для определения текущей ОС (isWindows (), isLinux ()...):

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

Пример:

if (PlatformUtil.isWindows()){
           ...
}

Допустим, у вас есть класс 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:

и так далее...

    private static String OS = System.getProperty("os.name").toLowerCase();

    public static void detectOS() {
        if (isWindows()) {

        } else if (isMac()) {

        } else if (isUnix()) {

        } else {

        }
    }

    private static boolean isWindows() {
        return (OS.indexOf("win") >= 0);
    }

    private static boolean isMac() {
        return (OS.indexOf("mac") >= 0);
    }

    private static boolean isUnix() {
        return (OS.indexOf("nux") >= 0);
    }

Попробуйте это, просто и легко

System.getProperty("os.name");
System.getProperty("os.version");
System.getProperty("os.arch");

Если вам интересно, как проект с открытым исходным кодом делает подобные вещи, вы можете проверить класс Terracotta (Os.java), который обрабатывает этот мусор здесь:

И вы можете увидеть похожий класс для обработки версий JVM (Vm.java и VmVersion.java) здесь:

Если вы работаете в среде, где важна безопасность, прочтите это.

Пожалуйста, воздержитесь от доверия к собственности, полученной через System#getProperty(String)подпрограмма! Собственно, почти все объекты недвижимости, включаяos.arch, os.name, а также os.version не только для чтения, как можно было бы ожидать - на самом деле все наоборот.

Прежде всего, любой код с достаточным разрешением на вызов System#setProperty(String, String)подпрограмма может изменять возвращаемый литерал по желанию. Однако это не обязательно основная проблема здесь, поскольку ее можно решить с помощью так называемогоSecurityManager, как описано более подробно здесь.

Фактическая проблема заключается в том, что любой пользователь может редактировать эти свойства при запуске JAR под вопросом (через -Dos.name=, -Dos.arch=, так далее.). Это означает, что невозможно определить, действительно ли эти свойства точны. По этой причине вот несколько дополнительных проверок, чтобы избежать подделки:

// The first thing we're able to do is to query the filesystem.
switch (java.io.File.separator)
{
    case "/":
        // Windows is a potential candidate.
        break;
    case "\\":
        // And here it could really be anything else.
        break;
    default:
        // There's probably something really wrong here by now.
        break;
}

Я думаю, что следующее может дать более широкое освещение в меньшем количестве строк

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

Ниже в коде показаны значения, которые вы можете получить из системного 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
\

Я считаю, что ОС Utils от Swingx делает свою работу.

Немного более короткая, чистая (и тщательно рассчитанная) версия основных ответов:

      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;
        }
    }
}

Взято из этого проекта https://github.com/RishiGupta12/serial-communication-manager

String osName = System.getProperty("os.name");
String osNameMatch = osName.toLowerCase();
if(osNameMatch.contains("linux")) {
    osType = OS_LINUX;
}else if(osNameMatch.contains("windows")) {
    osType = OS_WINDOWS;
}else if(osNameMatch.contains("solaris") || osNameMatch.contains("sunos")) {
    osType = OS_SOLARIS;
}else if(osNameMatch.contains("mac os") || osNameMatch.contains("macos") || osNameMatch.contains("darwin")) {
    osType = OS_MAC_OS_X;
}else {
}
String osName = System.getProperty("os.name");
System.out.println("Operating system " + osName);

Мне понравился ответ Вольфганга, просто потому, что я считаю, что такие вещи должны быть неприятностями...

так что я немного перефразировал это для себя, и думал поделиться этим:)

/**
 * 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://stackru.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;
    }
}

Вы можете просто использовать sun.awt.OSInfo#getOSType() метод

Вы можете получить имя типа ОС, используя

System.out.println(System.getProperty("os.name"));

Вы можете получить всю информацию, связанную с ОС:

public class MyFirstJavaProgram {

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

Будет выводить очень много деталей

- список свойств -

java.runtime.name = OpenJDK среда выполнения

sun.boot.library.path=/ USR / Библиотека / JVM / Java-1.8.0-OpenJDK-1.8.0...

java.vm.version = 25,65-B01

java.vm.vendor = Oracle Corporation

java.vendor.url = http://java.oracle.com/

path.separator =:

java.vm.name = OpenJDK 64-разрядная серверная виртуальная машина

file.encoding.pkg = sun.io

user.country = US

sun.java.launcher = SUN_STANDARD

sun.os.patch.level = неизвестно

java.vm.specification.name= Спецификация виртуальной машины Java

user.dir = / веб / ком / 1502258867_87863

java.runtime.version = 1.8.0_65-b17

java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment

java.endorsed.dirs = / USR / Библиотека / JVM / Java-1.8.0-OpenJDK-1.8.0...

os.arch = amd64

java.io.tmpdir = / TMP

line.separator =

java.vm.specification.vendor = Oracle Corporation

os.name = Linux

sun.jnu.encoding = UTF-8

java.library.path = / дом / CG / корень / GNUstep / Library / Librari...

java.specification.name = Спецификация API платформы Java

java.class.version=52,0

sun.management.compiler = 64-разрядные многоуровневые компиляторы HotSpot

os.version = 3.10.0-327.4.4.el7.x86_64

user.home = / USR / доли / HTTPD

user.timezone =

java.awt.printerjob = sun.print.PSPrinterJob

file.encoding = UTF-8

java.specification.version = 1,8

user.name = апаша

java.class.path = / дом / CG / корень / GNUstep / Library / Librari...

java.vm.specification.version = 1,8

sun.arch.data.model = 64

java.home = / USR / Библиотека / JVM / Java-1.8.0-OpenJDK-1.8.0...

sun.java.command = MyFirstJavaProgram

java.specification.vendor = Oracle Corporation

user.language = ы

awt.toolkit = sun.awt.X11.XToolkit

java.vm.info = смешанный режим

java.version = 1.8.0_65

java.ext.dirs = / USR / Библиотека / JVM / Java-1.8.0-OpenJDK-1.8.0...

sun.boot.class.path = / USR / Библиотека / JVM / Java-1.8.0-OpenJDK-1.8.0...

java.vendor = Oracle Corporation

File.separator = /

java.vendor.url.bug = http://bugreport.sun.com/bugreport/

sun.cpu.endian = немного

sun.io.unicode.encoding = UnicodeLittle

sun.cpu.isalist =

Этот код для отображения всей информации о типе операционной системы, имени, 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));
    }
}

В классе 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>

В противном случае просто найдите файл jar библиотеки jna (например, jna-5.2.0.jar) и добавьте его в путь к классам.

Для получения имени ОС просто используйте:

      Platform.getOS()

Допустим, вы хотите узнать, является ли платформа Linux:

      if (Platform.getOS().equals(Platform.OS_LINUX)) {
}

Точно так же в классе Platform определены константы для имен других операционных систем. Платформенный класс является частью org.eclipse.core.runtimeупаковка.

Поскольку Google точки «Котлин имя зева» на эту страницу, вот версия Котлина из @Memin «s ответа :

      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
}

Просто используйте com.sun.javafx.util.Utils как показано ниже.

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

ИЛИ ИСПОЛЬЗУЙТЕ

boolean isWindows = OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS);
       if (isWindows){
         // YOUR LOGIC HERE
       }
Другие вопросы по тегам