使用路径访问资源
介绍传统 File 类
在 Java 中,有两种方法可以对文件系统上的文件或路径进行建模。第一个是传统的 File 类。这里提到了这个类,并附带一个警告:除非有充分的理由,否则您不应该在代码中使用它。您应该优先使用 Path 接口,本节也将介绍该接口。与 Files 中的工厂方法一起,它为您提供了比 File 类更多的功能,以及更好的性能,尤其是在访问较大的文件和目录时。
话虽如此,由于它在传统代码中被广泛使用,因此了解 File 仍然可能对您很重要。在我们深入研究之前,让我们介绍一下这个类的主要概念。
File 类的实例可以表示文件系统上的任何内容:文件、目录、符号链接、相对路径或绝对路径。此实例是一个抽象概念。创建这样的实例不会在您的文件系统上创建任何内容。您可以使用此类查询您的文件系统,但您需要显式地执行此操作。
File 的实例不允许您访问它所代表的文件的内容。使用此实例,您可以检查此文件是否存在或是否可读(除其他事项外)。
文件由多个元素组成,这些元素由分隔符分隔,分隔符取决于您的文件系统。第一个元素可能是前缀,例如磁盘驱动器说明符、UNIX 根目录的斜杠。其他元素是名称。
创建 File 实例
您可以使用多个构造函数创建 File 类的实例
File(String pathName): 从您提供的路径创建文件。File(String parent, String child): 在parent目录中创建给定的文件。File(File parent, String child): 在parent目录中创建给定的文件,指定为File的实例。File(URI uri): 从URI创建文件。
获取文件的元素
以下方法为您提供有关此文件元素的信息
getName(): 返回此文件对象所表示的文件或目录的名称。这仅仅是序列中的最后一个名称。getParent(): 返回此抽象路径名的父路径名的字符串,如果此路径名没有命名父目录,则返回 null。getPath(): 返回此抽象路径名转换为路径名字符串。此方法与Path接口无关。getAbsolutePath(): 返回此抽象路径名的绝对路径名字符串。如果此抽象路径名已经是绝对路径名,则简单地返回路径名字符串。否则,此路径名将以系统相关的方式解析。getCanonicalPath(): 返回此抽象路径名的规范路径名字符串。规范路径名是绝对的、唯一的,并且与系统相关。此规范路径名的构造通常涉及从路径名中删除冗余名称,例如.和..,以及解析符号链接。
获取有关文件或目录的信息
其中一些方法可能需要对文件或目录的特殊权限。作为传统类,File 不会公开您的文件系统提供的所有安全属性。
isFile(),isDirectory(): 检查此抽象路径名是否表示现有文件或目录。exists(),canRead(),canWrite(),canExecute(): 检查此文件是否存在、是否可读、是否可以修改或是否可以执行。setReadable(boolean),setWritable(boolean),setExecutable(boolean): 允许您更改文件的相应安全属性。这些方法在操作成功时返回true。lastModified()和setLastModified(): 返回或设置此文件上次修改的时间。length(): 返回此抽象路径名所表示的文件的长度。isHidden(): 测试此抽象路径名命名的文件是否为隐藏文件。
操作文件和目录
一些方法允许您在文件系统上创建文件和目录。大多数方法与文件系统相关。请记住,这些方法是传统方法。您可以查看 将您的代码重构为使用 Path 部分,以将您的代码重构为使用 Path 接口和 Files 类中的等效方法。
createNewFile(): 尝试从该路径名创建一个新文件。如果该文件已存在,则创建将失败。如果文件创建成功,此方法返回true,否则返回false。delete(): 删除由该抽象路径名表示的文件或目录。如果该路径名表示一个目录,则该目录必须为空才能被删除。如果文件成功删除,此方法返回true,否则返回false。您应该优先使用Files.delete()方法,因为它在删除失败时会提供更多信息。mkdirs()和mkdir(): 创建一个由该抽象路径名表示的目录。mkdirs()会在需要时创建所有中间目录。renameTo(file): 重命名由该抽象路径名表示的文件。
介绍 Path 接口
在 Java SE 7 版本中引入的 Path 类是 java.nio.file 包的主要入口点之一。如果您的应用程序使用文件 I/O,您将需要了解此接口的强大功能。
版本说明:如果您有使用
java.io.File的 JDK7 之前的代码,您仍然可以使用File.toPath()方法来利用Path接口的功能。有关更多信息,请参见下一节。顾名思义,Path接口是文件系统中路径的编程表示。一个Path对象包含用于构造路径的文件名和目录列表,并用于检查、定位和操作文件。
一个 Path 实例反映了底层平台。在 Solaris 操作系统中,一个 Path 使用 Solaris 语法 (/home/joe/foo),而在 Microsoft Windows 中,一个 Path 使用 Windows 语法 (C:\home\joe\foo)。一个 Path 不是系统无关的。您不能比较来自 Solaris 文件系统和来自 Windows 文件系统的 Path,即使目录结构相同且两个实例都定位了相同的相对文件。
与 Path 对应的文件或目录可能不存在。您可以创建一个 Path 实例并以各种方式操作它:您可以追加到它,提取它的部分,将其与另一个路径进行比较。在适当的时候,您可以使用 Files 类中的方法来检查与 Path 对应的文件是否存在,创建文件,打开文件,删除文件,更改其权限等等。
重构您的代码以使用 Path
也许您有使用 java.io.File 的遗留代码,并且希望以最小的代码影响来利用 java.nio.file.Path 功能。
java.io.File 类提供了 toPath() 方法,该方法将旧式 java.io.File 实例转换为 java.nio.file.Path 实例,如下所示
Path input = file.toPath();
然后,您可以利用 Path 接口提供的丰富功能集。
例如,假设您有一些删除文件的代码
file.delete();
您可以修改此代码以使用 Files.delete() 工厂方法,如下所示
Path fp = file.toPath();
Files.delete(fp);
相反,Path.toFile() 方法为 Path 对象构造一个 java.io.File 对象。
由于 Java 中的文件 I/O 实现已在 Java SE 7 版本中完全重新架构,因此您不能将一种方法替换为另一种方法。如果您想使用 java.nio.file 包提供的丰富功能,最简单的解决方案是使用 File.toPath() 方法。但是,如果您不想使用这种方法或它不足以满足您的需求,则必须重写您的文件 I/O 代码。
这两个 API 之间没有一一对应的关系,但下表为您提供了一个关于 java.io.File API 中的功能映射到 java.nio.file API 中的哪些功能的一般了解,并告诉您可以在哪里获得更多信息。
上次更新: 2023 年 1 月 25 日