Как программно определить операционную систему на 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), который обрабатывает этот мусор здесь:
http://svn.terracotta.org/svn/tc/dso/trunk/code/base/common/src/com/tc/util/runtime/- http://svn.terracotta.org/svn/tc/dso/tags/2.6.4/code/base/common/src/com/tc/util/runtime/
И вы можете увидеть похожий класс для обработки версий 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
\
Немного более короткая, чистая (и тщательно рассчитанная) версия основных ответов:
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
}