在Java中查找用户主目录的最佳方法是什么?

难点在于解决方案应该是跨平台的;它应该可以在Windows 2000、XP、Vista、OS X、Linux和其他Unix变体上运行。我正在寻找一个代码片段,可以为所有平台完成这一点,以及一种检测平台的方法。

每个Java错误4787931,系统属性用户。home在Windows XP上不能正常工作,因此使用这个系统属性不是一个可接受的解决方案,因为它不是跨平台的。


当前回答

如果你想在windows上工作得很好,有一个叫做WinFoldersJava的包,它包装了本机调用来获得windows上的“特殊”目录。我们经常使用它,而且效果很好。

其他回答

System.getProperty("user.home");

参见JavaDoc。

实际上在Java 8中正确的方法是使用:

System.getProperty("user.home");

bug JDK-6519127已经被修复,并且在发布说明的“JDK 8和JDK 7之间的不兼容性”部分指出:

业务范围:Core Libs / java.lang 剧情简介 用于确定Windows上用户主目录的步骤已更改为遵循Microsoft推荐的方法。这种变化 可能在旧版本的Windows或where registry上可见 将设置或环境变量设置到其他目录。自然 不相容的 行为RFE 6519127

尽管这个问题已经很老了,我还是把它留给以后的参考。

其他人已经回答了我之前的问题,但一个有用的程序打印出所有可用的属性是:

for (Map.Entry<?,?> e : System.getProperties().entrySet()) {
    System.out.println(String.format("%s = %s", e.getKey(), e.getValue())); 
}

我会使用bug报告中详细描述的算法System.getenv(String),然后退回到使用用户。如果没有任何环境变量指示有效的现有目录,则使用Dir属性。这应该是跨平台的。

我认为,在Windows下,你真正想要的是用户名义上的“文档”目录。

当我在搜索Scala版本时,我所能找到的只是上面的McDowell的JNA代码。我在这里包含了我的Scala移植,因为目前没有更合适的地方了。

import com.sun.jna.platform.win32._
object jna {
    def getHome: java.io.File = {
        if (!com.sun.jna.Platform.isWindows()) {
            new java.io.File(System.getProperty("user.home"))
        }
        else {
            val pszPath: Array[Char] = new Array[Char](WinDef.MAX_PATH)
            new java.io.File(Shell32.INSTANCE.SHGetSpecialFolderPath(null, pszPath, ShlObj.CSIDL_MYDOCUMENTS, false) match {
                case true => new String(pszPath.takeWhile(c => c != '\0'))
                case _    => System.getProperty("user.home")
            })
        }
    }
}

与Java版本一样,您需要将Java Native Access(包括两个jar文件)添加到您所引用的库中。

很高兴看到JNA现在比发布原始代码时更容易做到这一点。