31

I need to find my documents path using Java. The following code doesn't give me "accurate" loation

System.getProperty("user.home");

What should be the other way around?

P.S: I don't want to use the JFileChooser Dirty trick.

Em Ae
  • 8,167
  • 27
  • 95
  • 162
  • You have to get your hands dirty one way or the other. A method using JNA/JNI can be found by the 'McDowell' poster: http://stackoverflow.com/questions/585534/what-is-the-best-way-to-find-the-users-home-directory-in-java – sethcall Mar 13 '12 at 02:44
  • the example posted there isn't a working solution with latest JNA – Em Ae Mar 13 '12 at 02:56
  • Well, I can't speak to that, but all signs point to a tough go at getting the right solution, and something like JNI seems required to do the 'right thing' (i.e., ask windows directly) – sethcall Mar 13 '12 at 02:57
  • 1
    Possible duplicate of [how to find "My Documents" folder](http://stackoverflow.com/questions/1503555/how-to-find-my-documents-folder) – IvanRF Oct 09 '15 at 21:56

8 Answers8

45

That's easy, JFileChooser finds it for you

new JFileChooser().getFileSystemView().getDefaultDirectory().toString();

I hope this helps someone

Michael
  • 41,989
  • 11
  • 82
  • 128
xchiltonx
  • 1,946
  • 3
  • 20
  • 18
42

Since the most upvoted answer from @xchiltonx uses JFileChooser I would like to add that, regarding performance, this is faster than using JFileChooser:

FileSystemView.getFileSystemView().getDefaultDirectory().getPath()

In my PC, JFileChooser aproach needed 300ms, and calling FileSystemView directly needed less than 100ms.

Note: The question is a possible duplicate of How to find “My Documents” folder in Java

IvanRF
  • 7,115
  • 5
  • 47
  • 71
  • This refers me to a folder that doesn't exist... c:\Users\\Documents. The documents folder on my system is called My Documents. – JavaLatte Mar 09 '16 at 16:27
  • 1
    @Javababe test the returned path on the file explorer. It could be a `symlink`. – IvanRF Mar 09 '16 at 16:57
  • you are right: the Documents folder does not show, but if you actually use it, it resolves to My Documents. Well, you learn something every day... :-) – JavaLatte Mar 09 '16 at 17:24
  • Downvoted because I'm not unconvinced of the performance benchmarks you claim. It's very easy to write a bad benchmark. Can you prove it? Doubtless, `FileSystemView.getFileSystemView()` is being called in both cases so your answer is preferable, if only because it avoids a throw-away object. – Michael Apr 05 '18 at 16:03
  • 7
    @Michael feel free to write your own benchmark and share the results. Nevertheless, you said it yourself, it is obvious that calling a function directly will be **faster** than creating an unneeded object with all its logic (UI, event listeners, etc.). – IvanRF Apr 05 '18 at 19:51
12

You can get it using a registry query, no need for JNA or admin rights for that.

Runtime.getRuntime().exec("reg query \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell 
Folders\" /v personal");

Obviously this will fail on anything other than Windows, and I am not certain whether this works for Windows XP.

EDIT: Put this in a working sequence of code:

String myDocuments = null;

try {
    Process p =  Runtime.getRuntime().exec("reg query \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\" /v personal");
    p.waitFor();

    InputStream in = p.getInputStream();
    byte[] b = new byte[in.available()];
    in.read(b);
    in.close();

    myDocuments = new String(b);
    myDocuments = myDocuments.split("\\s\\s+")[4];

} catch(Throwable t) {
    t.printStackTrace();
}

System.out.println(myDocuments);

Note this will lock the process until "reg query" is done, which might cause trouble dependeing on what you are doing.

pdinklag
  • 1,241
  • 1
  • 12
  • 28
  • Is there no way to query the registry directly from within Java? – Harry Johnston Mar 13 '12 at 20:19
  • It is generally possible using tools provided by the `java.util.prefs` package, but it is limited to the `SOFTWARE\JavaSoft\Prefs` tree and I have read about conflicts with Windows' UAC. Other than that, there are native solutions that provide a JNI DLL to read and write from the registry in Windows. However, obviously, this has a great impact on project distribution. The `reg` command should be safe to return quickly and not lock up, so I consider this the most preferable way of querying the registry, even though it is a little verbose (can always be put into a utility class) – pdinklag Mar 14 '12 at 19:30
3

Note in 2020: The ShellFolder class seems to be missing on Linux (tested with openjdk8), so IvanRF's answer is likely better.

Original answer:

The best way I've found is to use AWTs:

ShellFolder.get("fileChooserDefaultFolder");

I have redirected my Documents folder to the D: drive, and it successfully fetches this directory. It also does so in about 40 ms (on my machine). Using FileSystemView takes about 48 ms, and new JFileChooser() about 250 ms.

All three of these methods actually use ShellFolder under the hood, and the difference with FileSystemView is negligible, but calling it directly avoids the overhead of the other two.

Note: You can also cast this directly to File instead of implicitly getting the toString() method of it, which can help you further:

File documents = (File) ShellFolder.get("fileChooserDefaultFolder");
Magnus Bull
  • 1,027
  • 1
  • 10
  • 21
2

Using JNA you would do this:

String myDocsPath = Shell32Util.getFolderPath(ShlObj.CSIDL_PERSONAL);

JNA extracts a DLL on-the-fly and then uses JNI with this DLL to make Windows API calls. It hides all the JNI details from you though. Using JNA is as easy as using any other java library JAR.

Sarel Botha
  • 12,419
  • 7
  • 54
  • 59
1

"user.home" returns the home directory of the user, not the "My Documents" folder. On Windows, it would be "C:\Users\Username\" for Vista or 7, or "C:\Documents and Settings\Username" for XP

What you want is:

System.out.println(System.getProperty("user.home") + File.separatorChar + "My Documents");
nbarraille
  • 9,926
  • 14
  • 65
  • 92
  • 18
    That logic is not reliable. The documents folder may have been redirected elsewhere, or the name may be in another language. – Harry Johnston Mar 13 '12 at 03:25
  • In addition, the directory name may vary across OS versions, e.g. on my Windows 10 the directory name is just "Documents". In addition, there are Linux and OSX. – 18446744073709551615 Apr 28 '20 at 07:18
-2

this is what eclipse does to get the user document folder

System.getProperty("user.dir") //$NON-NLS-1$
                    + File.separator + "workspace")

Hope it's helpfull!

TuanAnh207
  • 90
  • 1
  • 11
-3
JFileChooser fileChooser = new JFileChooser();

fileChooser.setCurrentDirectory(new File(System.getProperty("user") + (File.separatorChar + "My Documents")));

int result = fileChooser.showOpenDialog(this);

if (result == JFileChooser.APPROVE_OPTION) {
    File selectedFile = fileChooser.getSelectedFile();
    System.out.println("Selected file: " + selectedFile.getAbsolutePath());
louisfischer
  • 1,968
  • 2
  • 20
  • 38
  • Just add this one + (File.separatorChar + "My Documents") – Jose Balicag Oct 21 '17 at 16:07
  • 3
    What is the benefit of your answer? You could at least explain why this would be a better way to do it. There are already an accepted answer and and another with a score of 18. – louisfischer Oct 21 '17 at 16:29
  • 1
    Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Oct 26 '17 at 16:38
  • I have seen at least on one version of Ubuntu Linux with non-English localization that the documents folder is not called "Documents" or "documents" (cannot remember what it was exactly, but it had nothing common with the English word). So the above code assumes English localization, Windows, and a version of Windows that calls the folder "My Documents", which is not true for Windows 10. – 18446744073709551615 Apr 28 '20 at 07:14