Java'da işletim sistemini programlı olarak nasıl belirlerim?


526

Java programımın programlı olarak çalıştığı ana bilgisayarın işletim sistemini belirlemek istiyorum (örneğin: Windows veya Unix platformunda olup olmadığım temelinde farklı özellikler yükleyebilmek istiyorum). % 100 güvenilirlikle bunu yapmanın en güvenli yolu nedir?

Yanıtlar:


617

Kullanabilirsiniz:

System.getProperty("os.name")

PS Bu kodu yararlı bulabilirsiniz:

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

Tek yaptığı, Java uygulamalarınız tarafından sağlanan tüm özellikleri yazdırmaktır. Özellikler aracılığıyla Java ortamınız hakkında neler bulabileceğiniz hakkında bir fikir verecektir. :-)


6
Kullanıyorum Windows 10ve yine de os.namebana veriyor Windows 8.1. Neden? Bu nereden geliyor?
Brian



82

Ekim 2008:

Statik bir değişken içinde önbellek öneriyoruz:

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
}

Bu şekilde, her işletim sistemi isteğinde bulunduğunuzda, başvurunuzun ömrü boyunca mülkü birden fazla almazsınız.


Şubat 2016: 7+ yıl sonra:

Windows 10 ile ilgili bir hata var (orijinal cevap sırasında mevcut değildi).
"Bkz ‘ Windows 10 için? Java'nın’os.name "


5
GetOSName işlevine OAOO temelinde katılıyorum (sadece bir kez); ancak, hash aramalarının hızı göz önüne alındığında önbellek tamamen gereksizdir.
Chris Jester-Young

6
Tamamen gereksiz biraz sert olabilir, hash aramaları bir referansa erişmekten daha pahalıdır. Her şey bağlama bağlıdır.
Craig Day

2
İyi puan ... Kötü bir uygulama olduğunu düşünüyorsanız aşağı oy vermekten çekinmeyin;)
VonC

5
Bu cevabı tekrar okuyorum. Eğer cache yapacaksanız, değerlerini önbelleğe isWindows, isUnixayrıca dize karşılaştırma zamanında tasarruf vs. bu arada sen.
Chris Jester-Young

2
@Brian True. Bu çok eski cevabı buna göre düzenledim, daha yakın olana değinmek için.
VonC

44

yukarıdaki cevaplardaki bazı bağlantılar kopmuş gibi görünüyor. Aşağıdaki kod geçerli kaynak koduna işaretçiler ekledim ve sonuç değerlendirilirken bir anahtar deyimi kullanılabilir bir cevap olarak bir numaralandırma ile kontrol işlemek için bir yaklaşım sunuyoruz:

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

Yardımcı sınıf:

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

3
(OS.indexOf ("darwin")> = 0) asla doğru olamaz çünkü bundan sonra gelir (OS.indexOf ("win")> = 0)
William

14
Yerel ayarlara duyarlı olan toLowerCase () kullandığından yukarıdaki kod yerel ayar sorunlarına sahip olabilir . Bu hususun özellikle i'leri küçük / büyük harfe çevirirken olduğu için, Türkiye'de küçük harfli i (ı) küçük harfli olurum ve i (İ) noktalı büyük harfli olur. Yani "WINDOWS" .toLowerCase (). İndexOf ("win") Türkiye'de -1 döndürecektir. "WINDOWS" .toLowerCase (Locale.ENGLISH) .indexOf ("win"), belirli bir dilin küçük harflerini yaparken her zaman bir yerel ayar iletin.
James Roper

@JamesRoper - thanx bunu düzeltti.
Wolfgang Fahl

7
OS.contains (...)
Grigory Kislin

42

Aşağıdaki JavaFX sınıflarının geçerli işletim sistemini (isWindows (), isLinux () ...) belirlemek için statik yöntemleri vardır:

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

Misal:

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

bu daha yüksek olmalı
habitatlar

3
Lütfen "com / sun / javafx / *" erişiminin artık önerilmediğini unutmayın (JDK 1.8.0_121 ile kontrol edin).
Michael Marton

1
@MichaelMarton İfadeniz için bir referansınız var mı?
Hummeling Engineering BV

@HummelingEngineeringBV: Sanırım bu benim tarafımdan bir hataydı. Tutulma Neon 4.6.3 ile çalışıyorum ve "Java Build Path" birkaç "Cesareti kırılmış: com / sun / javafx / **" uyarılarını gösteriyor. Ancak, bulduğum gibi, bu bir tutulma-böcek ve / veya -feature olur ( bağlantıya bakınız ).
Michael Marton

2
Kendimi bir kez daha düzeltmem gerekiyor. Java 9/10 + ile başlayarak, birkaç "com.sun. *" Paketi / API'si kaldırılmak üzere. Daha fazla bilgi için bu bağlantıya göz atın . Aslında bunun üzerine tökezledim çünkü bu paketlerin bazılarını kullanıyoruz. Eclipse 4.8 / JDK 10'a geçiş yaparken, eksik referanslar nedeniyle bunları ve diğer derleyici hatalarını düzeltmemiz gerekiyor.
Michael Marton

16

TL; DR

OS kullanımını erişmek için: System.getProperty("os.name").


Ama neden bir yardımcı sınıf yaratmıyorsunuz, onu yeniden kullanılabilir hale getirin! Ve muhtemelen birden fazla çağrıda çok daha hızlı. Temiz, berrak, daha hızlı!

Bu tür yardımcı işlevler için bir Util sınıfı oluşturun. Ardından her işletim sistemi türü için genel numaralandırmalar oluşturun.

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

Şimdi, herhangi bir sınıftan sınıfı aşağıdaki gibi kolayca çağırabilirsiniz (PS os değişkenini statik olarak ilan ettiğimizden, sistem türünü tanımlamak için sadece bir kez zaman harcayacaktır, daha sonra uygulamanız durana kadar kullanılabilir.)

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

Ve işte bu!


2
Bu kod parçasını açık kaynaklı bir projede kullanmak istiyorum ( github.com/openhab/openhab-addons ), bu senin için uygun mu?
Consti P

Evet lütfen kullanmaktan çekinmeyin.
Memin

13

Ulaşmaya çalıştığınız şeyin küçük bir örneği muhtemelen classaltındakilere benzer olacaktır:

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

Bu özel uygulama oldukça güvenilirdir ve evrensel olarak uygulanabilir olmalıdır. Sadece kopyalayıp istediğiniz gibi yapıştırın class.


10

Açık kaynak kodlu bir projenin böyle şeyleri nasıl yaptığını merak ediyorsanız, bu gereksiz dosyayı işleyen Terracotta sınıfına (Os.java) göz atabilirsiniz:

Ve burada JVM sürümlerini (Vm.java ve VmVersion.java) işlemek için benzer bir sınıf görebilirsiniz:


2
Terracotta sınıfı oldukça kapsamlı!
Stewart

3
lisans dikkat !!
harschware

ayrıca WolfgangtoLowerCase
Fahl'ın cevabında

9

Bunu deneyin, basit ve kolay

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

9

Bu projeden alınan 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 {
}

8

Aşağıdaki kod, Sistem API'sından alabileceğiniz değerleri, bu API aracılığıyla alabileceğiniz her şeyi gösterir.

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

Yanıtlar:-

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
\

7

Bunu bulmak SwingX dan OS Utils işi yapar.


2
Yukarıdaki bağlantı muhtemelen SwingX tanıtıcı dallar nedeniyle kopmuş gibi görünüyor; 1.6 sürümü burada: swingx.dev.java.net/source/browse/swingx/tags/SwingX-1-6/src/…
David Moles

1
@David Moles, teşekkürler. Ben cevap cevap-ok Tamam-şimdi bir tane ile güncelledim.
Richard Harrison



5
String osName = System.getProperty("os.name");
System.out.println("Operating system " + osName);

4

Sadece sun.awt.OSInfo # getOSType () yöntemini kullanabilirsiniz


Bu en iyi cevap olmalı! Sadece birisinin bunu burada belirtip belirtmediğini kontrol ediyordum.
Martin Krajčírovič

Bunun 'kısıtlı API' olması için herhangi bir geçici çözüm var mı? Bunu kullanmayı denemek istiyorum ama Eclipse'de bana bu uyarıyı veriyor. Eski bir jre kullanabilirim (örneğin jre1.8.0_171), ancak en son 1.8 jres kısıtlı olarak işaretlendi.
Brian_Entei

4

Güvenliğe duyarlı bir ortamda çalışıyorsanız, lütfen bunu okuyun.

Lütfen System#getProperty(String)altyordam yoluyla elde edilen bir mülke güvenmekten kaçının ! Aslında, neredeyse dahil olmak üzere her özellik os.arch, os.nameveos.version Tahmin edebileceğiniz ediyorum olarak salt okunur değil - bunun yerine, aslında oldukça zıt konum.

Her şeyden önce, System#setProperty(String, String)altyordamı çağırmak için yeterli izne sahip herhangi bir kod , döndürülen değişmez ifadeyi değiştirebilir. Bununla birlikte, bu burada birincil sorun olmak zorunda değildir SecurityManager, çünkü burada daha ayrıntılı olarak açıklandığı gibi bir sözde çözüm kullanılarak çözülebilir .

Asıl sorun, herhangi bir kullanıcının söz konusu çalıştırırken bu özellikleri düzenleyebilmesidir JAR. Bu, bu özelliklerin gerçekten doğru olup olmadığını belirlemenin bir yolu olmadığı anlamına gelir . Bu nedenle, kurcalamayı önlemek ve denemek için birkaç ek kontrol aşağıdadır:

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

Başka bir iyi fikir, işletim sistemine özgü dizinlerin varlığını kontrol etmektir. Hangi yaklaşımı seçerseniz edin, Java dilinin çapraz platform olarak girintili olduğunu unutmayın . Peki, neden aynısını yapmaya çalışmıyorsun?


3

Wolfgang'ın cevabını beğendim, çünkü böyle şeylerin consts olması gerektiğine inanıyorum ...

Bu yüzden biraz kendim için yeniden ifade ettim ve paylaşmayı düşündüm :)

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

Görünüşe göre "darwin" asla eşleştirilemez, çünkü "kazan" ı kontrol etmek zaten Windows'un geri dönmesine neden olacaktır.
tvkanters

orijinal
cevabımdaki

3
Tebrikler, sun.awt.OSInfo # getOSType'ı yeniden uyguladınız :)
Kirill Gamazkov

HHHHH ... iyi bir ... @Kirill Gamazkov Ben o zaman bulamadım .. işaret ettiğiniz için teşekkürler
TacB0sS

2

Sistem os türü, adı, java bilgileri vb. İle ilgili tüm bilgileri görüntülemek için bu kod.

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

1

Com.sun.jna.Platform sınıfında aşağıdaki gibi yararlı statik yöntemler bulabilirsiniz

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

ve daha fazlası.

Maven kullanıyorsanız sadece bağımlılık ekleyin

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

Aksi takdirde jna library jar dosyasını (ör. Jna-5.2.0.jar) bulun ve sınıf yoluna ekleyin.


1

Sadece com.sun.javafx.util.Utilsaşağıdaki gibi kullanın .

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

VEYA KULLAN

boolean isWindows = OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS);
       if (isWindows){
         // YOUR LOGIC HERE
       }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.