web-dev-qa-db-fra.com

Quel est le moyen multiplateforme d'obtenir le chemin d'accès au répertoire de données d'application local?

J'ai besoin d'un moyen indépendant de la plate-forme pour obtenir le chemin d'accès au répertoire de données d'application local. System.getenv("LOCALAPPDATA") ne semble fonctionner qu'avec Windows. Comment dois-je procéder?

44
missingfaktor

Vous pourriez probablement dire quelque chose comme (me contredire si je me trompe, ou si c'est une mauvaise approche)

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.

Notez que, dans ce code, je profite pleinement du fait que Java traite '/' De la même façon que '\\' Lorsqu'il s'agit de répertoires. Windows utilise '\\' comme pathSeparator, mais il est également satisfait de '/' (au moins Windows 7). Il est également insensible à la casse sur ses variables d'environnement; nous aurions pu tout aussi facilement dire workingDirectory = System.getenv("APPDATA"); et cela aurait tout aussi bien fonctionné.

39
Mike Warren

Personnellement, j'ai trouvé appdirs très utile pour des cas d'utilisation similaires. Il a des fonctions qui localisent différents types de répertoires utiles:

  • getUserDataDir
  • getUserConfigDir
  • getUserCacheDir
  • getUserLogDir
  • getSiteDataDir ← on dirait que c'est celui dont vous avez besoin
  • getSiteConfigDir

Les emplacements qu'il renvoie sont plus ou moins standards:

17
kirelagin

La quête est ancienne mais il me manque une réponse répertoriant les variables d'environnement au lieu de certains chemins absolus amusants. Je ne connais rien à OSX. ce post ne contient que des informations sur windows et linux.

Je n'ai pas assez de points pour étendre une réponse déjà existante, je dois donc en écrire une nouvelle.

Linux: Comme mentionné précédemment, il existe quelque chose comme freedesktop.org qui définit un standard que les distributions Linux essaient de remplir. Il existe également une sous-page définissant les variables d'environnement et leurs valeurs par défaut (si elles ne sont pas définies, elles sont vides par défaut. L'application doit faire correspondre la variable à la valeur par défaut). Lien vers cette page: freedesktop.org env vars

Vars défini comme pertinent pour cette question:

  • $ XDG_DATA_HOME ( local) (par défaut: $ HOME/.local/partager )
  • $ XDG_CONFIG_HOME ( local) (par défaut: $ HOME/.config )
  • $ XDG_DATA_DIRS ( global) (par défaut: /usr/local/partager/ ou /usr/partager/)
  • $ XDG_CONFIG_DIRS ( global) (par défaut: /etc/xdg )

Windows XP:

  • % APPDATA% (par défaut: C:\Documents and Settings {nom d'utilisateur}\Application Data )

  • % CommonProgramFiles% (par défaut: C:\Program Files\Fichiers communs ) (fichiers de programme partagés)

  • % CommonProgramFiles (x86)% (par défaut: C:\Program Files (x86)\Common Files ) (64 bits uniquement!) (Fichiers de programme partagés)

  • % ProgramFiles% (par défaut: % SystemDrive%\Program Files )

  • % ProgramFiles (x86)% (par défaut: % SystemDrive%\Program Files (x86) (uniquement en version 64 bits)) (64 bits uniquement!)

Windows Vista +:

  • % APPDATA% (par défaut: C:\Users {nom d'utilisateur}\AppData\Roaming ) (Partagé entre les postes de travail liés. Utilisateur local. Enregistrer les fichiers et les configurations)
  • % LOCALAPPDATA% (par défaut: C:\Users {username}\AppData\Local ) (Utilisateur local. Enregistrer les fichiers et les configurations)
  • % CommonProgramFiles% (par défaut: C:\Program Files\Fichiers communs ) (fichiers de programme partagés)
  • % CommonProgramFiles (x86)% (par défaut: C:\Program Files (x86)\Common Files ) (64 bits uniquement!) (Fichiers de programme partagés)

  • % ProgramFiles% (par défaut: % SystemDrive%\Program Files ) (Données statiques qui ne changeront pas après l'installation)

  • % ProgramFiles (x86)% (par défaut: % SystemDrive%\Program Files (x86) (uniquement en version 64 bits)) (64 bits uniquement!) (données statiques qui ne changeront pas après l'installation)

  • % ProgramData% (par défaut: % SystemDrive%\ProgramData ) ( Données modifiables affectant tous les utilisateurs)

En bref: Linux a deux variables d'environnement qui peuvent ne pas être définies (une pour les configurations, une pour les fichiers). Windows a autant que je puisse dire qu'une seule var d'environnement pour les configs et les fichiers ensemble. Veuillez les utiliser au lieu de chemins absolus.

10
Fjolnir Dvorak

Pour des quantités modérées de données, envisagez Java.util.prefs.Preferences, mentionné ici , ou javax.jnlp.PersistenceService, discuté ici . Les deux sont multi-plateformes.

9
trashgod

Il n'y a pas de moyen multiplateforme pour cela, car les concepts que les différents systèmes d'exploitation utilisent sont trop différents pour "s'éloigner". Je ne connais pas les conventions * nix et Mac, mais sous Windows il n'y a pas de "dossier de départ" et l'application doit spécifier si elle veut stocker des trucs dans le profil d'itinérance (C:\Users\<username>\AppData\Roaming\<application vendor>\<application name>\ par défaut) ou le profil local (C:\Users\<username>\AppData\Local\<application vendor>\<application name>\ par défaut).

Notez que vous ne pouvez pas coder en dur ces chemins, car sur une installation en réseau, ils peuvent être ailleurs. Vous ne devez pas non plus vous fier aux variables d'environnement car elles peuvent être modifiées par l'utilisateur. Votre application doit appeler la fonction SHGetKnownFolderPath de l'API Windows.

La différence entre les deux est que le profil local est spécifique à l'utilisateur et à la machine, tandis que le profil d'itinérance est spécifique à l'utilisateur, donc dans une configuration comme mon université, les applications de trucs mises dans le profil d'itinérance sont téléchargées sur le serveur et synchronisé avec l’ordinateur auquel je me connecte.

Il devrait incomber aux applications de choisir si les paramètres qu'elles souhaitent stocker sont locaux ou itinérants. Malheureusement Java ne permet pas aux applications de décider. À la place, il existe un paramètre global configurable par l'utilisateur qui détermine le dossier que vous obtiendrez.

2
marczellm

Le problème est que d'autres systèmes d'exploitation n'ont même pas un concept bien défini de "répertoire de données d'application". Il s'agit généralement d'un sous-répertoire masqué dans le répertoire de base de l'utilisateur avec un nom conventionnel qui peut être ou non le nom de l'application.


L'escargot mécanique commente ainsi:

Pas vrai. Linux en a un (~/.local par défaut), et je crois que OS X en a aussi.

Premièrement, ce n'est pas ~/.local. C'est ~/.local/share. (Ou du moins c'est sur ma machine Linux).

Deuxièmement, c'est une nouvelle idée. Il semble provenir du folk "freedesktop.org", via le XDG Base Directory Specification . Il n'est pas mentionné dans d'autres spécifications plus largement reconnues sur la façon dont les systèmes de fichiers Linux/UNIX doivent être organisés. Et notez ce qu'ils disent de leurs "normes" sur cette page: http://www.freedesktop.org/wiki/

Enfin, cette idée n'est pas implémentée par la majorité des commandes Linux. C'est assez peu scientifique, mais en regardant les répertoires cachés sur ma boîte Linux, je peux voir des signes d'au moins 40 applications distinctes soit en utilisant ~/ ou un sous-répertoire personnalisé. En revanche, il y a des signes de seulement 16 demandes dans ~/.local/share.

Une convention de dénomination mise en œuvre par moins de 1/3 des applications n'est guère un "concept bien défini" ... et certainement pas d'une manière cela permettrait de trouver le répertoire de données d'une application arbitraire de manière portable.

0
Stephen C