File Operations

Files类是java.nio.file包的另一个主要入口点。此类提供了一组丰富的静态方法,用于读取,写入和操作文件和目录。 Files方法适用于Path对象的实例。在 continue 其余部分之前,您应该熟悉以下常见概念:

释放系统资源

此 API 中使用的许多资源(例如流或通道)实现或扩展java.io.Closeableinterface。 Closeable资源的要求是,在不再需要close方法时必须调用该方法以释放资源。忽略关闭资源可能会对应用程序的性能产生负面影响。下一节中描述的try- with-resources 语句将为您处理此步骤。

Catching Exceptions

使用文件 I/O 时,意外的情况就成为了现实:预期存在文件(或不存在),程序无法访问文件系统,默认文件系统实现不支持特定功能, 等等。可能会遇到许多错误。

所有访问文件系统的方法都可以抛出IOException。最佳实践是通过将这些方法嵌入到 Java SE 7 发行版中引入的try- with-resources 语句中来catch这些异常。 try- with-resources 语句的优点在于,当不再需要时,编译器会自动生成代码以关闭资源。以下代码显示了外观:

Charset charset = Charset.forName("US-ASCII");
String s = ...;
try (BufferedWriter writer = Files.newBufferedWriter(file, charset)) {
    writer.write(s, 0, s.length());
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);
}

有关更多信息,请参见try-with-resources 语句

或者,您可以将文件 I/O 方法嵌入try块中,然后在catch块中catch任何异常。如果您的代码已打开任何流或通道,则应在finally块中将其关闭。上面的示例使用 try-catch-finally 方法看起来类似于以下内容:

Charset charset = Charset.forName("US-ASCII");
String s = ...;
BufferedWriter writer = null;
try {
    writer = Files.newBufferedWriter(file, charset);
    writer.write(s, 0, s.length());
} catch (IOException x) {
    System.err.format("IOException: %s%n", x);
} finally {
    if (writer != null) writer.close();
}

有关更多信息,请参见catch和处理异常

IOException外,许多特定的 exception 都扩展了FileSystemException。此类具有一些有用的方法,可以返回所涉及的文件(getFile),详细的消息字符串(getMessage),文件系统操作失败的原因(getReason)以及所涉及的“其他”文件(如果有的话(getOtherFile))。

以下代码段显示了如何使用getFile方法:

try (...) {
    ...    
} catch (NoSuchFileException x) {
    System.err.format("%s does not exist\n", x.getFile());
}

为了清楚起见,本课中的文件 I/O 示例可能未显示异常处理,但是您的代码应始终包含异常处理。

Varargs

指定标志时,多个Files方法接受任意数量的参数。例如,在以下方法签名中,CopyOption参数后的省略号表示该方法接受可变数量的参数或* varargs *,通常称为它们:

Path Files.move(Path, Path, CopyOption...)

当方法接受 varargs 参数时,可以将其传递给逗号分隔的值列表或值数组(CopyOption[])。

move示例中,可以按以下方式调用该方法:

import static java.nio.file.StandardCopyOption.*;

Path source = ...;
Path target = ...;
Files.move(source,
           target,
           REPLACE_EXISTING,
           ATOMIC_MOVE);

有关 varargs 语法的更多信息,请参见任意参数

Atomic Operations

某些Files方法(例如move)可以在某些文件系统中自动执行某些操作。

“原子文件操作”是不能中断或“部分”执行的操作。要么执行整个操作,要么操作失败。当有多个进程在文件系统的同一区域上运行时,这一点很重要,并且需要确保每个进程都访问一个完整的文件。

Method Chaining

许多文件 I/O 方法都支持方法链接的概念。

您首先调用一个返回对象的方法。然后,您立即在那个对象上调用一个方法,该方法返回另一个对象,依此类推。许多 I/O 示例都使用以下技术:

String value = Charset.defaultCharset().decode(buf).toString();
UserPrincipal group =
    file.getFileSystem().getUserPrincipalLookupService().
         lookupPrincipalByName("me");

该技术可以生成紧凑的代码,并使您避免声明不需要的临时变量。

什么是地球仪?

Files类中的两个方法都接受 glob 参数,但是* glob *是什么?

您可以使用 glob 语法指定 Pattern 匹配行为。

全局 Pattern 指定为字符串,并且与其他字符串(例如目录或文件名)匹配。 Glob 语法遵循几个简单规则:

在方括号中,*?\相匹配。

以下是 glob 语法的一些示例:

Note:

如果要在键盘上键入全局 Pattern,并且其中包含特殊字符之一,则必须将 Pattern 放在引号("*")中,使用反斜杠(\*),或者使用命令行支持的任何转义机制。

glob 语法功能强大且易于使用。但是,如果不足以满足您的需要,则也可以使用正则表达式。有关更多信息,请参见Regular Expressions类。

有关 glob sytnax 的更多信息,请参见FileSystem类中getPathMatcher方法的 API 规范。

Files类具有“链接意识”。每个Files方法要么检测遇到符号链接时的操作,要么提供一个选项,使您可以配置遇到符号链接时的行为。

首页