Find Directory for "Application Data" on Linux and MACintosh

Find directory for application data on linux and macintosh

this should work. just one thing: on linux it is preferred to keep settings in a hidden folder in user directory. So for linux, either put your folder under $HOME/.config, or start the name with the . to make it hidden.

Where to store application data (non-user specific) on Linux

It depends on what kind of data you're planning on storing. This answer is under the premise that you're storing and modifying data at run time.

Contrary to what others have suggested, I would recommend against using /usr/share for storage. From the Filesystem Hierarchy Standard:

The /usr/share hierarchy is for all
read-only architecture independent
data files.

As you're modifying data, this goes against the read-only nature of the /usr subsystem.

A seemingly better place to store your application state data would be /var, or more specifically, /var/lib. This also comes from the Hierarchy Standard. You could create a /var/lib/myapp, or if you're also using things like lock files or logs, you could leverage /var/lock or /var/log.

Have a deeper look at the standard as a whole (linked to above)—you might find a place that fits what you want to do even better.

Like Steve K, I would also recommend using the Preferences API for application preference data.

Shared data location for Linux and Mac OS X

I don't know if Qt provides an API for that. Here's the OS X specific information.

On OS X, it depends whether it's a GUI app or unix level support libraries. For a GUI app, it's the standard practice to have all the read-only data shared by all users inside the app bundle itself. Typically you have

  YourApp.app/
YourApp.app/Contents
YourApp.app/Contents/MacOS
YourApp.app/Contents/MacOS/YouApp .... this is the binary
YourApp.app/Contents/Resources/ .... here are all the shared data

The GUI presents the directory YourApp.app as the application itself, so that you can copy/move it around without any problem.
If that's not possible, it's recommended to use the subdirectory of

/Library/Application Support/name_of_your_app/

for data shared among users.

It's a bad idea to have a mutable, shared data among users on a machine; in general it's impossible due to the access restrictions. Note that a standard user might not have, and in fact usually does not have an administrative right to write into a shared location.

For mutable data specific to a user, use

~/Library/Application Support/name_of_your_app/

See this Apple guideline for more info.

Application's data folder in Mac


/Users/USERNAME/Library/Application Support/

Edit:

This answer has drawn a lot of upvotes despite its minimalistic nature. Therefore, I want to point out the things mentioned in the comments here to make them more visible:

  • There are several other folders being used for application data / configuration, as mentioned in this answer.
  • If writing an application, don't hardcode that path. Instead, use macOS' API to retrieve it. This question has several answers for both ObjectiveC and Swift.

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.

Where can I store program data? (OS, Java)

The system property user.home is a property that you can use.

Path path = Paths.get(System.getProperty("user.home"));

if (Files.isDirectory(path) && Files.exists(path)) {
Path myFolder = path.resolve("my_folder");

if (Files.notExists(myFolder)) {
Files.createDirectory(myFolder);
}
}

Storing non-user specific application data on Mac & Linux - Permissions

What do you mean by non-user specific application data?

  • Read-only resources needed by application, such as localization strings or button icons:

    • on Mac they are stored in application bundle itself, in Resources subfolder
    • on Linux, they can be stored near application binary, in /opt/<app>/etc for instance.

  • Read/write properties, such as serial number:

    • you can consider this information as user-specific application data, so it should go somewhere in $HOME directory
    • you can consider this information as computer-wide application data, in which case its setting should be perfomed during software installation process, i.e., with administrative privileges.

Find place for dedicated application folder

There should be, but there isn't. I even submitted a bug/RFE about it, but as far as I know, it was never accepted. Here's what I use:

public class ApplicationDirectories {
private static final Logger logger =
Logger.getLogger(ApplicationDirectories.class.getName());

private static final Path config;

private static final Path data;

private static final Path cache;

static {
String os = System.getProperty("os.name");
String home = System.getProperty("user.home");

if (os.contains("Mac")) {
config = Paths.get(home, "Library", "Application Support");
data = config;
cache = config;
} else if (os.contains("Windows")) {
String version = System.getProperty("os.version");
if (version.startsWith("5.")) {
config = getFromEnv("APPDATA", false,
Paths.get(home, "Application Data"));
data = config;
cache = Paths.get(home, "Local Settings", "Application Data");
} else {
config = getFromEnv("APPDATA", false,
Paths.get(home, "AppData", "Roaming"));
data = config;
cache = getFromEnv("LOCALAPPDATA", false,
Paths.get(home, "AppData", "Local"));
}
} else {
config = getFromEnv("XDG_CONFIG_HOME", true,
Paths.get(home, ".config"));
data = getFromEnv("XDG_DATA_HOME", true,
Paths.get(home, ".local", "share"));
cache = getFromEnv("XDG_CACHE_HOME", true,
Paths.get(home, ".cache"));
}
}

/** Prevents instantiation. */
private ApplicationDirectories() {
}

/**
* Retrieves a path from an environment variable, substituting a default
* if the value is absent or invalid.
*
* @param envVar name of environment variable to read
* @param mustBeAbsolute whether enviroment variable's value should be
* considered invalid if it's not an absolute path
* @param defaultPath default to use if environment variable is absent
* or invalid
*
* @return environment variable's value as a {@code Path},
* or {@code defaultPath}
*/
private static Path getFromEnv(String envVar,
boolean mustBeAbsolute,
Path defaultPath) {
Path dir;
String envDir = System.getenv(envVar);
if (envDir == null || envDir.isEmpty()) {
dir = defaultPath;
logger.log(Level.CONFIG,
envVar + " not defined in environment"
+ ", falling back on \"{0}\"", dir);
} else {
dir = Paths.get(envDir);
if (mustBeAbsolute && !dir.isAbsolute()) {
dir = defaultPath;
logger.log(Level.CONFIG,
envVar + " is not an absolute path"
+ ", falling back on \"{0}\"", dir);
}
}
return dir;
}

/**
* Returns directory where the native system expects an application
* to store configuration files for the current user. No attempt is made
* to create the directory, and no checks are done to see if it exists.
*
* @param appName name of application
*/
public static Path configDir(String appName)
{
return config.resolve(appName);
}

/**
* Returns directory where the native system expects an application
* to store implicit data files for the current user. No attempt is made
* to create the directory, and no checks are done to see if it exists.
*
* @param appName name of application
*/
public static Path dataDir(String appName)
{
return data.resolve(appName);
}

/**
* Returns directory where the native system expects an application
* to store cached data for the current user. No attempt is made
* to create the directory, and no checks are done to see if it exists.
*
* @param appName name of application
*/
public static Path cacheDir(String appName)
{
return cache.resolve(appName);
}
}

Some notes:

I'm not sure the code for older Windows versions is even necessary, as Java 8 doesn't run on Windows XP.

The XDG Directory Specification says “All paths set in these environment variables must be absolute. If an implementation encounters a relative path in any of these variables it should consider the path invalid and ignore it.”

How to save application data for use across users in OS X

The developer documentation covering this is a bit of a large topic:

  • https://developer.apple.com/library/Mac/referencelibrary/GettingStarted/GS_DataManagement_MacOSX/_index.html#//apple_ref/doc/uid/TP40009046
  • https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010672

According to the File System Programming guide you should make a specific subdirectory inside /Library/Application\ Support for your app to store app data common to all users on the system. I'd use reverse domain name notation such as com.yourcompany.yourapp or something else unlikely to collide with another app's use of the common directory for this.

You might also look into using an existing app bundler for OS X such as https://bitbucket.org/infinitekind/appbundler rather than hard code paths to file locations.



Related Topics



Leave a reply



Submit