Вопрос по java, cross-platform – Каков кросс-платформенный способ получения пути к локальному каталогу данных приложения?

40

Мне нужен независимый от платформы способ получения пути к локальному каталогу данных приложения.System.getenv("LOCALAPPDATA") Кажется, работает только с Windows. Как мне это сделать?

Проголосовал за закрытие вопроса, так как нашел ответ в другой ветке. missingfaktor
Смотрите такжеCreate a temporary directory in Java. trashgod
Другая проблема состоит в том, что другие ОС даже не различают локальную и перемещаемую части профиля :-) Joey

Ваш Ответ

7   ответов
9

java.util.prefs.PreferencesупоминаетсяВот, или жеjavax.jnlp.PersistenceServiceобсуждалиВот, Оба кроссплатформенные.

Хранение данных непосредственно вPreferences исключает необходимость указыватьworkingDirectory, какPreferences уже тезисы
@thrashgod не могли бы вы привести пример того, как получить локальный каталог данных приложения изjava.util.Preferences?
-2

String currentDir = new File(".").getAbsolutePath();

или это:

System.getProperty("user.dir")

Я предпочитаю первый вариант

С уважением

Я полагаю, вы имели в виду "user.home". & Quot; user.dir & Quot; текущий рабочий каталог, который не обязательно находится там, где находится папка AppData
0

что другие операционные системы даже не имеют четко определенной концепции «каталога данных приложения». Обычно это просто скрытый подкаталог в домашнем каталоге пользователя с условным именем, которое может быть или не быть именем приложения.

Механическая улитка комментирует так:

Not true. Linux has one (~/.local by default), and I believe OS X also does.

Во-первых, это не~/.local, это~/.local/share, (Или, по крайней мере, на моей машине с Linux).

Во-вторых, это новая идея. Похоже, что он произошел от "freedesktop.org" народ, черезСпецификация XDG Base Directory, В других, более широко признанных спецификациях о том, как должны быть организованы файловые системы Linux / UNIX, не упоминается. И обратите внимание, что они говорят о своих «стандартах». на этой странице:http://www.freedesktop.org/wiki/

Наконец, эта идея не реализована большинством команд Linux. Это довольно ненаучно, но, глядя на скрытые каталоги на моем компьютере с Linux, я вижу признаки как минимум 40 различных приложений, использующих~/ или пользовательский подкаталог. В отличие от этого есть признаки только 16 приложений в~/.local/share.

Соглашение об именах, которое реализуетсяless than 1/3rd приложений вряд ли является «четко определенной концепцией» ... и, конечно, не таким способом, который позволял бы находить каталог данных произвольного приложения переносимым способом.

Широко «уважаемый» ~ = широко применяется. Когда & gt; 50% "классического" приложения реализуют это, тогда вы можете сделать этот аргумент. До тех пор ~ / .local является стремлением, а не широко принятой конвенцией ... ИМО.
@StephenC OS X имеет один предопределенный. Если вы используете API-интерфейс Cocoa или его базовые части, как это делает среда выполнения Java для Mac, он предопределен.
@StephenC: стандарты Freedesktopare широко уважаемый в Linux. Для этой конкретной спецификации, хотя все еще есть много программ, которые не переключались (необходимость переключения едва ли актуальна),GNOME а такжеKDE оба считают это целью. Значительная часть программ уважает это.
@Mechanicalsnail - ваш комментарий - ерунда. Смотрите мое подробное опровержение в Ответе.
Не правда. Линукс есть один (~/.local по умолчанию), и я считаю, что OS X также делает.
1

потому что понятия, которые используют разные ОС, слишком различны, чтобы «абстрагироваться». Я не знаком с соглашениями * nix и Mac, но в Windows нет & quot; домашней папки & quot; и приложение должно указать, хочет ли оно хранить вещи вroaming profile (C:\Users\<username>\AppData\Roaming\<application vendor>\<application name>\ по умолчанию) илиlocal profile (C:\Users\<username>\AppData\Local\<application vendor>\<application name>\ по умолчанию).

Обратите внимание, что вы не можете жестко закодировать эти пути, потому что при сетевой установке они могут быть где-то еще. Вы не должны полагаться на переменные окружения либо потому, что они могут быть изменены пользователем. Ваша заявка должна позвонитьSHGetKnownFolderPath функция Windows API.

Разница между ними заключается в том, что локальный профиль зависит от пользователя и компьютера, в то время как перемещаемый профиль зависит от пользователя, поэтому в настройках, подобных моему университету, приложения, помещаемые в перемещаемый профиль, загружаются на сервер и синхронизируется с тем компьютером, на котором я вхожу.

Приложения должны нести ответственность за выбор локальных или роуминговых настроек. К сожалению, Java не позволяет приложениям решать это. Вместо этого существует глобальный настраиваемый пользователем параметр, который определяет, какую папку вы получите.

31

вы могли бы сказать что-то вроде (противоречить мне, если я ошибаюсь, или если это плохой подход)

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.

Обратите внимание, что в этом коде я в полной мере использую преимущества Java'/' такой же как'\\' при работе с каталогами. Windows использует'\\' как pathSeparator, но доволен'/', тоже. (По крайней мере, Windows 7 является.) Она также нечувствительна к регистру переменных среды; мы могли бы так же легко сказатьworkingDirectory = System.getenv("APPDATA"); и это сработало бы так же хорошо.

@MikeWarren Я проверял это"user.home" возврат имущества/home/username как это делает Windows. И в качестве подсказки, используйте каталог, который начинается с точки, если вы хотите скрыть его какuser.home это папка пользователя и обычно папка программы скрыта (начните с точки).
@MikeWarren Хороший подход! Почему бы просто не сказатьworkingDirectory = System.getenv("AppData") и затем проверьте, является ли он нулевым, чтобы изменить его на местоположение в UNIX?
стал популярным, но этот ответ еще не принят? @MikeWarren
Apple советует не кодироватьApplication Support папка. Например. Ваш код не будет работать в изолированных приложениях.
Важный знак: высказываниеprivate final String workingDirectory = System.getenv("AppData") + File.separatorChar + ourFolder; а потомprivate File dataFolder = new File("workingDirectory"); System.out.println("Our dataFolder was " + ((dataFolder.mkdir()) ? "" : "not ") + "created successfully"); НЕ гарантирует, что родительский каталогdataFolder будетAppData папка. // В моем случае это было сохранено вRoaming.
8

но я пропускаю список ответов, а не забавные абсолютные пути. Я ничего не знаю о OSX. Этот пост содержит только информацию о Windows и Linux.

У меня недостаточно очков, чтобы расширить уже существующий ответ, поэтому я должен написать новый.

Linux: Как упоминалось ранее, существует нечто вроде freedesktop.org, который определяет стандарт, который дистрибутивы linux пытаются выполнить. Существует также подстраница, определяющая переменные среды и их значения по умолчанию (если они не установлены, они по умолчанию пусты. Приложение должно сопоставить переменную со значением по умолчанию). Ссылка на эту страницу: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) %CommonProgramFi,les% (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 есть две переменные среды, которые не могут быть установлены (одна для конфигов, одна для файлов). Насколько я знаю, в Windows есть только одна переменная окружения для конфигов и файлов. Пожалуйста, используйте их вместо абсолютных путей.

Места Mac OS X проверяютсяhere.
11

appdirs быть очень полезным для подобных случаев использования. Этоимеет функции которые находят различные виды полезных каталогов:

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

Места, которые он возвращает, более или менее стандартны:

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

Похожие вопросы