The difficulty is that it should be cross platform. Windows 2000, XP, Vista, OSX, Linux, other unix variants. I am looking for a snippet of code that can accomplish this for all platforms, and a way to detect the platform.
Now, you should be aware of bug 4787931 that user.home
does not work correctly, so please do not provide me of texbook answers, I can find these myself in the manuals.
-
System.getProperty(String name) should do it with the right property:
System.getProperty("user.home");
Other useful properties can be found here
Bruno Ranschaert : Same answer as above, see comments above. This seems to be an exercise in replication. -
System.getProperty("user.home");
See the JavaDoc.
Bruno Ranschaert : Nope, not a correct answer, this is the same one as above. Yes, I did not only read the JavaDocs, but I also tried it out on all platforms before asking this question! The answer is not so simple. -
Others have answered the question before me but a useful program to print out all available properties is:
for (Map.Entry<?,?> e : System.getProperties().entrySet()) { System.out.println(String.format("%s = %s", e.getKey(), e.getValue())); }
Joachim Sauer : I wouldn't depend on this, because not all properties are standardized. Instead check the JavaDoc for System.getProperties() to find out which properties are guaranteed to exist.oxbow_lakes : That may be true but it's still pretty useful for a newbie I would think! I'm not sure it deserves 2 downvotes :-( -
Since you specifically mention bug 4787391 I assume you are not satisfied with the System.getProperty("user.home") functionality. Are you sure? the user.home approach seems to work in a very large number of cases. If you have read the bug page you will find that a 100% bulletproof solution on Windows is hard, because Windows has a shifting concept of what the home directory means.
If user.home isn't good enough for you I would suggest choosing a definition of 'home directory' for windows and using it, getting the appropriate environment variable with System.getenv(String).
Bruno Ranschaert : Finally, this is the best solution after all. -
The concept of a HOME directory seems to be a bit vague when it comes to Windows. If the environment variables (HOMEDRIVE/HOMEPATH/USERPROFILE) aren't enough, you may have to resort to using native functions via JNI or JNA. SHGetFolderPath allows you to retrieve special folders, like My Documents (CSIDL_PERSONAL) or Local Settings\Application Data (CSIDL_LOCAL_APPDATA).
Sample JNA code:
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); } }
Matt Solnit : FYI, the folder that corresponds to the user's home directory is CSIDL_PROFILE. See http://msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx.Bruno Ranschaert : Yes, this is an elaborate version for the Windows case. -
I would use the algorithm detailed in the bug report using System.getenv(String), and fallback to using the user.dir property if none of the environment variables indicated a valid existing directory. This should work cross-platform.
I think, under Windows, what you are really after is the user's notional "documents" directory.
0 comments:
Post a Comment