JDK7 引入 NIO2,对以前那些枯燥乏味的操作,例如将文件读取到一个字符串中,或者复制文件,现在都变得简单了。NIO2 让 Java1.4 引入的 NIO 库重新焕发了活力。
在你学习如何调用这些简单的文件操作之前,你首先应该了解一下取代了 File 类的 Path 接口。接下来,你将了解如何读取和写入文件。最后,我们将学习文件和目录操作。
NIO2(New I/O 2)是 Java 7 引入的对非阻塞 I/O 操作的改进和扩展。
NIO2 提供了更强大和灵活的文件和文件系统操作功能。它引入了java.nio.file包,其中包含了一系列新的类和接口,用于处理文件、目录和文件属性等。
一些关键的特性和优势包括:
更好的文件系统遍历:可以更方便地遍历目录结构。
文件属性访问:能够获取和操作文件的详细属性。
异步 I/O 操作:支持异步地执行文件操作,提高了应用的性能和响应性。
例如,在处理大量文件的场景中,使用 NIO2 的异步操作可以在文件处理的同时,不阻塞其他任务的执行,从而提高整个应用的效率。又如,在需要动态监控文件系统变化的应用中,NIO2 提供了方便的机制来实现这一功能。
Paths 类由便捷的静态方法组成,通过转换路径字符串或 URI,返回一个 Path。方法定义如下:
static Path get(String first, String... more) 将一个路径字符串或一连串字符串(连接后形成一个路径字符串)转换为一个 Path 对象。
static Path get(URI uri) 将给定的 URI 转换为 Path 对象。
示例:
package com.hxstrive.jdk7.nio2; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; /** * Paths 示例 * @author hxstrive.com */ public class PathsDemo { public static void main(String[] args) { Path path = Paths.get("D:\\", "temp", "test.txt"); System.out.println(path); // D:\temp\test.txt path = Paths.get("D:\\temp\\test.txt"); System.out.println(path); // D:\temp\test.txt try { path = Paths.get(new URI("file:///D:/temp/test.txt")); System.out.println(path); // D:\temp\test.txt } catch (URISyntaxException e) { e.printStackTrace(); } } }
注意:静态方法 Paths.get() 可以接受一个或多个字符串,然后它将这些字符串用文件系统默认的路径分隔符(对于类似 UNIX 文件系统为 /,对于 Windows 系统为 \)连接起来。然后它对结果进行解析,如果结果在指定的文件系统上不是一个有效的路径,那么它会抛出一个 InvalidPathException 异常。例如:
Path path = Paths.get("D:\\", "temp", "D:\\test.txt"); System.out.println(path); // 异常:java.nio.file.InvalidPathException: Illegal char <:> at index 10: D:\\temp\D:\test.txt
路径(Path)是一个含有多个目录名称的序列,也可能带着一个文件名,如 “D:\tmp\root\test.txt”。路径的第一部分可能是一个根目录,例如 /(对于 Linux 或 Unix) 或者 C:\(对于 Windows)。
注意:由根目录开始的路径称为绝对路径,反之则称为相对路径。
例如,下面我们创建了一个绝对路径和一个相对路径:
package com.hxstrive.jdk7.nio2; import java.nio.file.Path; import java.nio.file.Paths; /** * JDK7 NIO2 * @author hxstrive.com */ public class PathDemo1 { public static void main(String[] args) { // 绝对路径 Path absolute = Paths.get("D:","tmp", "root", "test.txt"); System.out.println(absolute.getFileName()); // 相对路径 Path relative = Paths.get("project","conf", "user.properties"); System.out.println(relative.getFileName()); } }
注意:同 File 对象类似,Path 对象并不一定非要对应一个实际存在的文件,它只是一个文件名的抽象序列。要创建一个文件,首先要构造一个路径,然后调用其他方法来创建对应的文件。
将当前路径与另一个路径结合,返回一个新的路径。例如:
Path path1 = Paths.get("/home/hxstrive"); Path path2 = Paths.get("documents/file.txt"); Path path = path1.resolve(path2); System.out.println(path); // 输出:\home\hxstrive\documents\file.txt
返回一个从当前路径到另一个路径的相对路径。例如:
Path path1 = Paths.get("/home/hxstrive/documents"); Path path2 = Paths.get("/home/hxstrive/images"); Path path = path1.relativize(path2); System.out.println(path); // 输出:..\images
返回当前路径的绝对路径。如果指定的路径不是绝对路径,那么它会根据 “用户目录” —— 即调用 JVM 的路径进行解析。例如:
Path path1 = Paths.get("./documents/file.txt"); Path path = path1.toAbsolutePath(); System.out.println(path); // 输出:E:\jdk7\.\documents\file.txt
注意:如果你在 E:\jdk7 路径下执行该程序。
该方法针对某个路径的父目录进行解析,并产生一个兄弟路径。例如:
Path path1 = Paths.get("D:\\temp\\test.txt"); Path path = path1.resolveSibling("demo.txt"); System.out.println(path); // 输出:D:\temp\demo.txt
该方法会去掉所有冗余的 . 和 .. 目录(以及任何文件系统认为是冗余的目录)。例如:
Path path1 = Paths.get("D:\\.\\temp\\..\\test.txt"); Path path = path1.normalize(); System.out.println(path); // 输出:D:\test.txt
getFileName() 返回路径的文件名部分。
getParent() 返回路径的父目录路径。
getRoot() 返回路径的根目录部分。
例如:
Path 接口提供了许多有用的方法,可以获取路径的一部分,或者将它们与其他路径组合起来。下面的代码示例展示了其中的一些方法:
Path p = Paths.get("D:\\" , "temp", "properties", "my.properties"); Path parent = p.getParent(); System.out.println(parent); // 获取路径,为 D:\temp\properties Path file = p.getFileName(); System.out.println(file); // 获取文件名,为 my.properties Path root = p.getRoot(); System.out.println(root); // 获取起始路径,D:\
注意:你偶尔可能需要与使用 File 类(而非 Path 接口)的遗留 API 之间进行相互操作,为此 Path 接口提供了一个 toFile 方法,同时 File 类也提供了一个 toPath 方法。例如:
Path p = Paths.get("D:\\" , "temp", "properties", "my.properties"); File file = p.toFile(); System.out.println(file); // D:\temp\properties\my.properties Path path = file.toPath(); System.out.println(path); // D:\temp\properties\my.properties