HOWTO · Java

在 Java 中获取用户主目录

这篇文章向你展示了如何在 Java 中获取用户主目录。

本页内容

使用 Java 的 System.getProperty("user.home") 获取主目录值,返回类型为 String。如果 API 需要文件系统对象,可将该值转换为 Path 或 File。只有在应用需要特定环境变量,并且能够处理变量缺失或配置不同的情况时,才应将 HOME、USERPROFILE 等环境变量作为替代方案。

使用 System.getProperty("user.home") 获取用户主目录

user.home 是用于保存当前用户主目录的 Java 系统属性。System.getProperty() 会以字符串形式返回该属性的值。这个值来自正在运行的 Java 环境:它可以在 JVM 启动时配置,因此可能与操作系统中预期的位置不同。读取该值不会检查路径是否存在,也不会确认进程是否有权访问它。

运行下面的示例:

本节中的代码以及显示的标签或输出仍为英文。

public class Main {
  public static void main(String[] args) {
    String home = System.getProperty("user.home");
    System.out.println("User home: " + home);
  }
}

打印出的路径取决于机器和 Java 进程的配置,因此不存在适用于所有环境的固定输出路径。该示例只打印属性值,不会创建或检查目录。

在文件操作中使用主目录

如果要解析子路径,或将某个位置传给文件操作,文件系统 API 通常需要路径对象。在 Java 11 及更高版本中,可使用 Path.of(home) 将返回的字符串转换为路径;如果项目面向支持 java.nio.file 的较早 Java 版本,则可使用 Paths.get(home)。对于要求 File 的 API,也可以使用 File 类。

例如,按前文所述获取 home 后,Path homePath = Paths.get(home); 会为该位置创建一个 Path。使用 Path settings = homePath.resolve(".config").resolve("myapp"); 可以解析一个子路径。这样会按照默认文件系统的规则组合路径组件,而不是用斜杠拼接字符串。之后可根据需要,将生成的 Path 传给 Files.newBufferedReader() 或 Files.createDirectories() 等 API。仅创建 Path 不会在磁盘上创建任何内容;应选择实际执行所需文件操作的方法,并处理相应的 I/O 错误。

如果现有 API 需要 File,可用 new File(home) 创建它。应根据调用方 API 接受的类型来选择;对于较新的文件系统代码,通常优先使用 Path。这两种转换都不会验证目标位置,也不会授予访问权限。

从环境变量读取 HOME 或 USERPROFILE

System.getenv("HOME") 和 System.getenv("USERPROFILE") 会读取指定的环境变量;如果请求的变量对当前进程不可用,System.getenv() 会返回 String 或 null。类 Unix 环境中通常使用 HOME,Windows 环境中通常使用 USERPROFILE,但应用、容器、服务和启动配置各不相同。变量名称和值都取决于具体环境;不能仅凭操作系统名称就认定相应变量一定存在,或一定指向所需目录。

如果应用确实需要其中一个变量,应先检查它是否为 null,再将其转换为路径或使用它。还应决定变量缺失时应用该如何处理,例如回退到 user.home,或报告配置问题。如果任务只是获取 Java 配置的主目录值,优先使用 Java 属性。不要为了查找一个变量而打印完整环境,其中可能包含无关配置或敏感值。

项目已依赖 Apache Commons IO 时再使用它

如果项目已经包含 Apache Commons IO,可以使用 FileUtils.getUserDirectory() 获取 File,或使用 FileUtils.getUserDirectoryPath() 获取字符串形式的路径。这些便捷方法并不能消除对 Java 环境所提供值的考量,也不足以成为仅为这一次查询而添加依赖的理由。只有在项目已使用该库,或需要其更广泛的 I/O 工具时,才应引入它。

选择合适的方法并处理限制

对于一般的 Java 文件系统操作,可通过 System.getProperty() 读取 user.home,再将其转换为所用 API 需要的 Path 或 File。只有当应用明确依赖某个环境变量时,才选择 System.getenv(),并处理变量可能缺失或经过自定义配置的情况。如果项目已经使用 Apache Commons IO,且其返回类型适合代码,也可以使用该库。

应将主目录值视为起始路径,而不是目录存在、可写或适合作为应用数据目录的证明。根据任务需要,使用文件系统 API 检查或创建目录,并处理这些 API 所说明的 I/O 错误。将路径查询与文件系统操作分开,可以明确应用所依赖的假设。