What is the cross-platform way of obtaining the path to the local application data directory?

You could probably say something like (contradict me if I am wrong, or if this a bad approach)

private String workingDirectory;
//here, we assign the name of the OS, according to Java, to a variable...
private String OS = (System.getProperty("os.name")).toUpperCase();
//to determine what the workingDirectory is.
//if it is some version of Windows
if (OS.contains("WIN"))
{
    //it is simply the location of the "AppData" folder
    workingDirectory = System.getenv("AppData");
}
//Otherwise, we assume Linux or Mac
else
{
    //in either case, we would start in the user's home directory
    workingDirectory = System.getProperty("user.home");
    //if we are on a Mac, we are not done, we look for "Application Support"
    workingDirectory += "/Library/Application Support";
}
//we are now free to set the workingDirectory to the subdirectory that is our 
//folder.

Note that, in this code, I am taking full advantage that Java treats '/' the same as '\\' when dealing with directories. Windows uses '\\' as pathSeparator, but it is happy with '/', too. (At least Windows 7 is.) It is also case-insensitive on it's environment variables; we could have just as easily said workingDirectory = System.getenv("APPDATA"); and it would have worked just as well.


Personally, I found appdirs to be very helpful for similar use-cases. It has functions that locate different kinds of useful directories:

  • getUserDataDir
  • getUserConfigDir
  • getUserCacheDir
  • getUserLogDir
  • getSiteDataDir ← looks like this is the one you need
  • getSiteConfigDir

The locations it returns are more or less standard:

  • On Unix it follows XDG Base Directory Specification.
  • On Windows it invokes SHGetFolderPath.
  • On macOS it uses well-known hardcoded paths.

The questing is old but I am missing an answer listing environment vars instead of some funny absolute paths. I do not know anything about OSX. this post only contains information about windows and linux.

I have not enough points to extend an already existing answer so I have to write a new one.

Linux: As previously mentioned there exists something like freedesktop.org which is defining a standard the linux distributions are trying to fulfill. There is also a subpage defining environment variables and their default values (If they are not set they are empty by default. The application has to match the variable to the default). Link to that page: freedesktop.org env vars

Vars defined relevant for this question:

  • $XDG_DATA_HOME (local) (defaults to: $HOME/.local/share)
  • $XDG_CONFIG_HOME (local) (defaults to: $HOME/.config)
  • $XDG_DATA_DIRS (global) (defaults to: /usr/local/share/ or /usr/share/)
  • $XDG_CONFIG_DIRS (global) (defaults to: /etc/xdg)

Windows XP:

  • %APPDATA% (defaults to: C:\Documents and Settings{username}\Application Data)

  • %CommonProgramFiles% (defaults to: C:\Program Files\Common Files) (shared program files)

  • %CommonProgramFiles(x86)% (defaults to: C:\Program Files (x86)\Common Files) (64-bit only!) (shared program files)

  • %ProgramFiles% (defaults to: %SystemDrive%\Program Files)

  • %ProgramFiles(x86)% (defaults to: %SystemDrive%\Program Files (x86) (only in 64-bit version)) (64-bit only!)

Windows Vista +:

  • %APPDATA% (defaults to: C:\Users{username}\AppData\Roaming) (Shared between linked workstations. User local. Save files and configs)
  • %LOCALAPPDATA% (defaults to: C:\Users{username}\AppData\Local) (User local. Save files and configs)
  • %CommonProgramFiles% (defaults to: C:\Program Files\Common Files) (shared program files)
  • %CommonProgramFiles(x86)% (defaults to: C:\Program Files (x86)\Common Files) (64-bit only!) (shared program files)

  • %ProgramFiles% (defaults to: %SystemDrive%\Program Files) (Static data that will not change after installation)

  • %ProgramFiles(x86)% (defaults to: %SystemDrive%\Program Files (x86) (only in 64-bit version)) (64-bit only!) (Static data that will not change after installation)

  • %ProgramData% (defaults to: %SystemDrive%\ProgramData) (Changeable data affecting all users)

In short: Linux has two environment variables which might not be set (one for configs, one for files). Windows has as far as I can tell only one environment var for configs and files together. Please use these instead of absolute paths.


For moderate amounts of data, consider java.util.prefs.Preferences, mentioned here, or javax.jnlp.PersistenceService, discussed here. Both are cross-platform.


There is no cross platform way for that, because the concepts that the different OS-s use are too different to "abstract away". I am not familiar with *nix and Mac conventions, but on Windows there is no "home folder" and the application has to specify whether it wants to store stuff in the roaming profile (C:\Users\<username>\AppData\Roaming\<application vendor>\<application name>\ by default) or the local profile (C:\Users\<username>\AppData\Local\<application vendor>\<application name>\ by default).

Note that you cannot hardcode these paths, because on a networked installation they might be somewhere else. You shouldn't rely on environment variables either because they can be modified by the user. Your application should call the SHGetKnownFolderPath function of the Windows API.

The difference between the two is that the local profile is specific to the user and the machine, while the roaming profile is specific to the user, so in a setup like my university, stuff apps put in the roaming profile are uploaded to the server and synced to whichever computer I log in to.

It should be the responsibility of applications to choose whether the settings they want to store are local or roaming. Unfortunately Java does not allow apps to decide this. Instead there is a global user-configurable setting that determines which folder you'll get.