2009-12-06 117 views
44

如何确定使用Java的Windows的32位或64位体系结构?如何确定使用Java的Windows的32位或64位体系结构?

谢谢。

+7

这是一个非常普遍的问题,不仅仅是针对windows。 – prasanna 2009-12-06 20:55:54

+1

为什么你想知道这个? Java应该在任何有JVM的操作系统上运行 - 您的Java程序不应该在乎它是否在32位或64位操作系统上运行。 – Jesper 2009-12-07 08:37:42

+5

@Jesper因为多次运行java并不是唯一的目的。很多时候,你可能已经开发了一个专门用于64位机器(或32位机器)的程序/应用程序(原因可能是任何事情)。在这样的地方,我需要检查是什么版本的windows体系结构.. – Chani 2012-05-25 11:55:48

回答

48

请注意,os.arch属性只会给你的JRE的架构,而不是底层的操作系统。

如果在64位系统上安装32位JRE,System.getProperty("os.arch")将返回x86

为了实际确定的底层架构,您将需要编写一些本地代码。请参阅this post以获取更多信息(以及指向示例本机代码的链接)

-1
System.getProperty("os.arch"); 
+9

在64b窗口,但32b jvm它为我打印“x86”。所以我想它并没有说系统的版本,而是虚拟机。 – 2009-12-06 21:43:55

+0

是的,这是一个受欢迎的'陷阱'。 – Bozho 2009-12-06 21:45:22

+1

@Bozho称它为“gotcha”或称之为“答案不回答问题”...... – glglgl 2015-08-21 08:10:00

-4

您可以使用系统属性中的os.arch属性来查找。

Properties pr = System.getProperties(); 
System.out.println(pr.getProperty("os.arch")); 

如果你是32位,它应该显示i386或东西

+1

它将是'x86' – Bozho 2009-12-06 20:56:39

+1

谢谢,我在我的Linux机器上使用它,它显示了i386。 – prasanna 2009-12-07 22:11:14

+1

在运行32位JVM的64位操作系统上,这将返回x86,表示32位。虽然这对于JVM是正确的,但操作系统是错误的,这是OP要求的。 – CMerrill 2014-07-24 20:04:18

66

我并不完全相信读取os.arch系统变量。虽然它适用于用户在64位系统上运行64位JVM的情况。如果用户在64位系统上运行32位JVM,则不起作用。

以下代码适用于正确检测Windows 64位操作系统。在Windows 64位系统上,环境变量 “Programfiles(x86)”将被设置。它不会在32位系统上设置,并且java会将其读为null。

boolean is64bit = false; 
if (System.getProperty("os.name").contains("Windows")) { 
    is64bit = (System.getenv("ProgramFiles(x86)") != null); 
} else { 
    is64bit = (System.getProperty("os.arch").indexOf("64") != -1); 
} 

对于其他操作系统,如Linux或Solaris或Mac,我们也会看到这个问题。所以这不是一个完整的解决方案。对于mac,你可能是安全的,因为苹果锁定JVM以匹配操作系统。但是Linux和Solaris等等,他们仍然可以在他们的64位系统上使用32位的JVM。所以请谨慎使用。

+1

“我不完全相信读'os.arch'系统变量。”这种行为的原因是,例如, [JNI](https://en.wikipedia.org/wiki/Java_Native_Interface)对于了解[JVM](https://en.wikipedia.org/wiki/Java_virtual_machine)**的重要性非常重要, OS(如果您需要将Java代码加载到您自己的平台相关共享库中,则它们需要与JVM相同)。 – pevik 2016-04-13 09:34:16

+1

+1经过相当多的研究后,我将使用它。但我很好奇,在这台机器上(Windows 8.1 64位),环境变量'ProgramFiles(x86)'未列在“This PC”/ Properties/Advanced System Settings/Environment Variables下,但System.getenv(“ProgramFiles (x86)“)'确实返回值”C:\ Program Files(x86)“,这当然很棒,因为听起来像这样的变量不能被用户修改或删除;是这样吗? 'ProgramFiles(x86)'是某种“内部”环境变量吗? – SantiBailors 2016-12-13 14:00:31

1

你可以试试这个代码,我认为这是更好地检测JVM

模型
boolean is64bit = System.getProperty("sun.arch.data.model").contains("64"); 
+2

OP询问OS而不是JVM – leonbloy 2014-01-30 20:22:33

+0

对我来说就像一个魅力。谢谢! – 2016-04-29 15:06:02

0

也许这是不是最好的方式,但它的工作原理。

我所做的就是获取Windows为Program Files x86文件夹配置的“环境变量”。我的意思是Windows x64有文件夹(Program Files x86),而x86不是。因为用户可以更改Enviroment Variables中的Program Files路径,或者他/她可以在C:\中创建一个目录“Program Files(x86)”,所以我将不会使用该文件夹的检测,而是使用“Program”的“Enviroment Path”文件(x86)“与Windows注册表中的变量。

public class getSystemInfo { 

    static void suckOsInfo(){ 

    // Get OS Name (Like: Windows 7, Windows 8, Windows XP, etc.) 
    String osVersion = System.getProperty("os.name"); 
    System.out.print(osVersion); 

    String pFilesX86 = System.getenv("ProgramFiles(X86)"); 
    if (pFilesX86 !=(null)){ 
     // Put here the code to execute when Windows x64 are Detected 
    System.out.println(" 64bit"); 
    } 
    else{ 
     // Put here the code to execute when Windows x32 are Detected 
    System.out.println(" 32bit"); 
    } 

    System.out.println("Now getSystemInfo class will EXIT"); 
    System.exit(0); 

    } 

} 
+0

那么,用户布尔已经以相同的方式,但在一个更好的代码。 – Blackgeo32 2013-10-18 17:22:27

3

我使用命令提示符(命令 - > wmic OS获取OSArchitecture)来获取操作系统体系结构。下面的程序可帮助获得所有必需的参数:

import java.io.*; 

public class User { 
    public static void main(String[] args) throws Exception { 

     System.out.println("OS --> "+System.getProperty("os.name")); //OS Name such as Windows/Linux 

     System.out.println("JRE Architecture --> "+System.getProperty("sun.arch.data.model")+" bit.");  // JRE architecture i.e 64 bit or 32 bit JRE 

     ProcessBuilder builder = new ProcessBuilder(
      "cmd.exe", "/c","wmic OS get OSArchitecture"); 
     builder.redirectErrorStream(true); 
     Process p = builder.start(); 
     String result = getStringFromInputStream(p.getInputStream()); 

     if(result.contains("64")) 
      System.out.println("OS Architecture --> is 64 bit"); //The OS Architecture 
     else 
      System.out.println("OS Architecture --> is 32 bit"); 

     } 


    private static String getStringFromInputStream(InputStream is) { 

     BufferedReader br = null; 
     StringBuilder sb = new StringBuilder(); 

     String line; 
     try { 

      br = new BufferedReader(new InputStreamReader(is)); 
      while ((line = br.readLine()) != null) { 
       sb.append(line); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (br != null) { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     return sb.toString(); 

    } 

} 
0

(仅Windows)检查 C:\ WINDOWS \ SysWOW64中 存在。 如果该目录存在,则它是一个64位的进程。 否则,这是一个32位的过程。

0

声明:请不要低估这是一个重复的答案,因为我想分享我的Java代码解决方案(这一个都是本机代码)。

我想加上James Van Huis先生的回答; 由于属性os.arch: System.getProperty("os.arch"); 返回JRE的位数,这实际上可能非常有用。 来自文章:

在你的代码中,你首先需要检查IntPtr的大小,如果它返回8,那么你在64位操作系统上运行。如果它返回4,那么你正在运行一个32位应用程序,所以现在你需要知道你是在本地运行还是在WOW64下运行。

因此,IntPtr大小检查与通过查看“os.arch”执行的检查相同。之后,您可以继续确定该进程是在本机运行还是在WOW64下运行。

这可以通过使用jna库(例如,NativeLibrary)来完成,该库提供了所需的本机功能。

//test the JRE here by checking the os.arch property 
//go into the try block if JRE is 32bit 
try { 
    NativeLibrary kernel32Library = NativeLibrary.getInstance("kernel32"); 
    Function isWow64Function = kernel32Library.getFunction("IsWow64Process"); 

    WinNT.HANDLE hProcess = Kernel32.INSTANCE.GetCurrentProcess(); 
    IntByReference isWow64 = new IntByReference(0); 
    Boolean returnType = false; 
    Object[] inArgs = { 
     hProcess, 
     isWow64 
    }; 
    if ((Boolean) isWow64Function.invoke(returnType.getClass(), inArgs)) { 
     if (isWow64.getValue() == 1) { 
       //32bit JRE on x64OS 
     } 
    } 
} catch (UnsatisfiedLinkError e) { //thrown by getFunction 

} 

像这样的东西可能也行,但我会建议的第一个版本,因为它是我在x64和32位JRE测试的x64操作系统的一个。此外,它应该是更安全的方式,因为在下面你不会实际检查“IsWow64Process”函数是否存在。

这里我添加了一个JRE检查的例子,尽管它不难找到,但它是完整的。

Map<String, Integer> archMap = new HashMap<String, Integer>(); 
archMap.put("x86", 32); 
archMap.put("i386", 32); 
archMap.put("i486", 32); 
archMap.put("i586", 32); 
archMap.put("i686", 32); 
archMap.put("x86_64", 64); 
archMap.put("amd64", 64); 
//archMap.put("powerpc", 3); 
this.arch = archMap.get(SystemUtils.OS_ARCH); 
if (this.arch == null) { 
    throw new IllegalArgumentException("Unknown architecture " + SystemUtils.OS_ARCH); 
} 
相关问题