【问题标题】:What is the cross-platform way of obtaining the path to the local application data directory?获取本地应用数据目录路径的跨平台方式是什么?
【发布时间】:2012-06-22 06:14:35
【问题描述】:

我需要的是一种独立于平台的方式来获取本地应用程序数据目录的路径。 System.getenv("LOCALAPPDATA") 似乎只适用于 Windows。我该怎么办?

【问题讨论】:

标签: java cross-platform


【解决方案1】:

任务很旧,但我缺少一个答案列表环境变量,而不是一些有趣的绝对路径。我对OSX一无所知。这篇文章只包含有关 windows 和 linux 的信息。

我没有足够的分数来扩展已经存在的答案,所以我必须写一个新的。

Linux: 如前所述,存在诸如 freedesktop.org 之类的东西,它定义了 linux 发行版试图实现的标准。 还有一个子页面定义环境变量及其默认值(如果未设置,则默认为空。应用程序必须将变量与默认值匹配)。链接到该页面:freedesktop.org env vars

与此问题相关的变量定义:

  • $XDG_DATA_HOME(本地)(默认为:$HOME/.local/share)
  • $XDG_CONFIG_HOME(本地)(默认为:$HOME/.config)
  • $XDG_DATA_DIRS(全局)(默认为:/usr/local/share/ 或 /usr/share/ )
  • $XDG_CONFIG_DIRS(全局)(默认为:/etc/xdg)

Windows XP:

  • %APPDATA%(默认为:C:\Documents and Settings{username}\Application Data)

  • %CommonProgramFiles%(默认为:C:\Program Files\Common Files)(共享程序文件)

  • %CommonProgramFiles(x86)%(默认为:C:\Program Files (x86)\Common Files)(仅限 64 位!)(共享程序文件)

  • %ProgramFiles%(默认为:%SystemDrive%\Program Files)

  • %ProgramFiles(x86)%(默认为:%SystemDrive%\Program Files (x86)(仅限 64 位版本))(64 - 仅限位!)

Windows Vista +:

  • %APPDATA%(默认为:C:\Users{username}\AppData\Roaming)(在链接的工作站之间共享。用户本地。保存文件和配置)
  • %LOCALAPPDATA%(默认为:C:\Users{username}\AppData\Local)(本地用户。保存文件和配置)
  • %CommonProgramFiles%(默认为:C:\Program Files\Common Files)(共享程序文件)
  • %CommonProgramFiles(x86)%(默认为:C:\Program Files (x86)\Common Files)(仅限 64 位!)(共享程序文件)

  • %ProgramFiles%(默认为:%SystemDrive%\Program Files)(安装后不会更改的静态数据)

    李>
  • %ProgramFiles(x86)%(默认为:%SystemDrive%\Program Files (x86)(仅限 64 位版本))(64 -bit only!)(安装后不会更改的静态数据)

  • %ProgramData%(默认为:%SystemDrive%\ProgramData)(影响所有用户的可变数据)

简而言之: Linux 有两个可能未设置的环境变量(一个用于配置,一个用于文件)。据我所知,Windows 只有一个环境变量用于配置和文件。请使用这些而不是绝对路径。

【讨论】:

  • 检查 Mac OS X 位置here。
  • Windows XP 没有 %LOCALAPPDATA% 变量,但它有文件夹,它位于 %USERPROFILE%\Local Settings\Application Data
【解决方案2】:

你可能会说类似(如果我错了,或者如果这是一个不好的方法,请反驳我)

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 使用'\\' 作为路径分隔符,但它也对'/' 感到满意。 (至少 Windows 7 是。)它的环境变量也不区分大小写;我们可以很容易地说workingDirectory = System.getenv("APPDATA");,它也会同样有效。

【讨论】:

  • 一个重要的旁注:说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.
  • Apple 建议不要硬编码 Application Support 文件夹。例如。对于沙盒应用程序,您的代码将失败。
  • @MikeWarren 我已经测试了"user.home" 属性返回/home/username 就像Windows 一样。作为提示,如果您想隐藏它,请使用以点开头的目录,因为user.home 是用户文件夹,通常程序文件夹是隐藏的(以点开头)。
  • @MikeWarren 不错的方法!为什么不简单地说workingDirectory = System.getenv("AppData"),然后测试它是否为空以将其更改为 UNIX 位置?
  • 很受欢迎,但这个答案还没有被接受? @迈克沃伦
【解决方案3】:

就我个人而言,我发现appdirs 对于类似的用例非常有帮助。它has functions 定位不同种类的有用目录:

  • getUserDataDir
  • getUserConfigDir
  • getUserCacheDir
  • getUserLogDir
  • getSiteDataDir ← 看起来这就是你需要的那个
  • getSiteConfigDir

它返回的位置或多或少是标准的:

【讨论】:

    【解决方案4】:

    没有跨平台的方式,因为不同操作系统使用的概念差异太大,无法“抽象”。我不熟悉 *nix 和 Mac 约定,但在 Windows 上没有“主文件夹”,应用程序必须指定是否要在 漫游配置文件 中存储内容(默认为C:\Users\<username>\AppData\Roaming\<application vendor>\<application name>\ ) 或本地配置文件(默认为C:\Users\<username>\AppData\Local\<application vendor>\<application name>\)。

    请注意,您不能对这些路径进行硬编码,因为在网络安装中,它们可能位于其他位置。您也不应该依赖环境变量,因为它们可以由用户修改。您的应用程序应调用 Windows API 的 SHGetKnownFolderPath 函数。

    两者之间的区别在于,本地配置文件是特定于用户和机器的,而漫游配置文件是特定于用户的,所以在像我大学这样的设置中,放置在漫游配置文件中的东西应用程序被上传到服务器并同步到我登录的任何计算机。

    应用程序有责任选择它们要存储的设置是本地的还是漫游的。不幸的是,Java 不允许应用程序来决定这一点。相反,有一个全局用户可配置设置来确定您将获得哪个文件夹。

    【讨论】:

      【解决方案5】:

      对于中等数量的数据,请考虑java.util.prefs.Preferences,提及here,或javax.jnlp.PersistenceService,讨论here。两者都是跨平台的。

      【讨论】:

      • @thrashgod 能否提供一个示例,说明如何从java.util.Preferences 检索本地应用数据目录?
      • 将数据直接存储在Preferences 中无需指定workingDirectory,因为Preferences 已经抽象了位置。
      【解决方案6】:

      你可以用这个

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

      或者这个:

      System.getProperty("user.dir")
      

      我更喜欢第一个选项

      问候

      【讨论】:

      • 我相信你的意思是“user.home”。 “user.dir”为当前工作目录,不保证是AppData文件夹所在位置
      猜你喜欢
      • 1970-01-01
      • 2011-11-16
      • 1970-01-01
      • 2021-10-09
      • 2011-05-01
      • 1970-01-01
      • 2017-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多