What is the best way to find the home directory of users in Java?

The difficulty is that it has to be a cross platform. Windows 2000, XP, Vista, OSX, Linux, other unix options. I am looking for a piece of code that can do this for all platforms, and a way to discover the platform.

Now you should know error 4787931 that user.home is not working correctly, so please do not provide me with answers to tutorials, I can find them in the manuals.

+199
java cross-platform
Feb 25 '09 at 10:46
source share
8 answers

The bug you are referring to is fixed (bug 4787391) is fixed in Java 8. Even if you are using an older version of Java, the System.getProperty("user.home") approach is probably still the best. The user.home approach seems to work in a very large number of cases. A 100% bulletproof solution on Windows is tricky because Windows has a shifting concept of what a home directory means.

If user.home not enough for you, I would suggest choosing a home directory definition for Windows and using it, getting the appropriate environment variable with System.getenv(String) .

+266
Feb 25 '09 at 15:05
source share

Actually with Java 8, the correct way is to use:

 System.getProperty("user.home"); 

The bug JDK-6519127 was fixed , and the section "Incompatibilities between JDK 8 and JDK 7" in the notes :

Scope: Core Libs / java.lang

Summary

The steps used to determine the user's home directory on Windows have changed in accordance with the method recommended by Microsoft. This change may occur in older versions of Windows, or in the registry, parameters or environment variables are set to other directories. Nature of incompatibility

 behavioral RFE 6519127 

Despite the old question, I leave this for future reference.

+104
Nov 13 '14 at 14:52
source share

The concept of the HOME directory seems a little vague when it comes to Windows. If the variables (HOMEDRIVE / HOMEPATH / USERPROFILE) are not enough, you may need to use your own functions through JNI or JNA . SHGetFolderPath allows you to extract special folders such as My Documents (CSIDL_PERSONAL) or Local Settings \ Application Data (CSIDL_LOCAL_APPDATA).

JNA Code Example:

 public class PrintAppDataDir { public static void main(String[] args) { if (com.sun.jna.Platform.isWindows()) { HWND hwndOwner = null; int nFolder = Shell32.CSIDL_LOCAL_APPDATA; HANDLE hToken = null; int dwFlags = Shell32.SHGFP_TYPE_CURRENT; char[] pszPath = new char[Shell32.MAX_PATH]; int hResult = Shell32.INSTANCE.SHGetFolderPath(hwndOwner, nFolder, hToken, dwFlags, pszPath); if (Shell32.S_OK == hResult) { String path = new String(pszPath); int len = path.indexOf('\0'); path = path.substring(0, len); System.out.println(path); } else { System.err.println("Error: " + hResult); } } } private static Map<String, Object> OPTIONS = new HashMap<String, Object>(); static { OPTIONS.put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE); OPTIONS.put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE); } static class HANDLE extends PointerType implements NativeMapped { } static class HWND extends HANDLE { } static interface Shell32 extends Library { public static final int MAX_PATH = 260; public static final int CSIDL_LOCAL_APPDATA = 0x001c; public static final int SHGFP_TYPE_CURRENT = 0; public static final int SHGFP_TYPE_DEFAULT = 1; public static final int S_OK = 0; static Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class, OPTIONS); /** * see http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx * * HRESULT SHGetFolderPath( HWND hwndOwner, int nFolder, HANDLE hToken, * DWORD dwFlags, LPTSTR pszPath); */ public int SHGetFolderPath(HWND hwndOwner, int nFolder, HANDLE hToken, int dwFlags, char[] pszPath); } } 
+26
Feb 25 '09 at 17:10
source share
 System.getProperty("user.home"); 

See JavaDoc .

+23
Feb 25 '09 at 10:53
source share

Others answered my question, but a useful program for listing all available properties:

 for (Map.Entry<?,?> e : System.getProperties().entrySet()) { System.out.println(String.format("%s = %s", e.getKey(), e.getValue())); } 
+15
Feb 25 '09 at 11:03
source share

Since I was looking for a version of Scala, all I could find was the McDowell JNA code above. Here I turn on the Scala port, as it is currently not suitable.

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

As with the Java version, you will need to add Java Native Access , including both jar files, to your specified libraries.

It's nice to see that JNA now makes it a lot easier than when the source code was sent.

+4
Jun 22 '14 at 13:30
source share

I would use the algorithm described in detail in the error report using System.getenv (String), and cancel the use of the user.dir property if none of the environment variables specified a valid existing directory. This should work cross-platform.

I think that under Windows, what you really are is a custom conditional document directory.

+2
Feb 26 '09 at 8:34
source share

If you want something that works well on windows, there is a package called WinFoldersJava that wraps its own call to get 'special' directories on Windows. We often use it and work well.

0
Sep 05 '17 at 10:24 on
source share



All Articles