文章插图
JAVA 之所以能够霸占编程语言的榜首 , 其强大、丰富的类库功不可没 , 几乎所有的编程问题都能在其中找到解决方案 。但在早期的版本当中 , 输入输出(I/O)流并不那么令开发者感到愉快:
1)JDK 1.4 之前的 I/O 没有缓冲区的概念、不支持正则表达式、支持的字符集编码有限等等;
2)JDK 1.4 的时候引入了非阻塞 I/O , 也就是 NIO 1.0 , 但遍历目录很困难 , 不支持文件系统的非阻塞操作等等 。
为了突破这些限制 , JDK 1.7 的时候引入了新的 NIO , 也就是本篇文章的主角——NIO 2.0 。
01、基石:Path
Path 既可以表示一个目录 , 也可以表示一个文件 , 就像 File 那样——当然了 , Path 就是用来取代 File 的 。
1)可以通过 Paths.get() 创建一个 Path 对象 , 此时 Path 并没有真正在物理磁盘上创建;参数既可以是一个文件名 , 也可以是一个目录名;绝对路径或者相对路径均可 。
2)可以通过 Files.notExists() 确认 Path(目录或者文件) 是否已经存在 。
3)可以通过 Files.createDirectory() 创建目录 , 此时目录已经在物理磁盘上创建成功 , 可通过资源管理器查看到 。
4)可以通过 Files.createFile() 创建文件 , 此时文件已经在物理磁盘上创建成功 , 可通过资源管理器查看到 。
5)可以通过 toAbsolutePath() 查看 Path 的绝对路径 。
6)可以通过 resolve() 将 Path 连接起来 , 参数可以是一个新的 Path 对象 , 也可以是对应的字符串 。
具体的代码如下:
public class Wanger { public static void main(String[] args) { // 相对路径 Path dir = Paths.get("chenmo"); // 输出 dir 的绝对路径 System.out.println(dir.toAbsolutePath()); // 输出:D:programjava.gitjava_demochenmo if (Files.notExists(dir)) { try { // 如果目录不存在 , 则创建目录 Files.createDirectory(dir); } catch (IOException e1) { e1.printStackTrace(); } } // 这时候 chenmo.txt 文件并未创建 // 通过 resolve 方法把 dir 和 chenmo.txt 链接起来 Path file = dir.resolve("chenmo.txt"); // 输出 file 的绝对路径 System.out.println(file.toAbsolutePath()); // 输出:D:programjava.gitjava_demochenmochenmo.txt if (Files.notExists(file)) { try { // 如果文件不存在 , 则创建文件 Files.createFile(file); } catch (IOException e) { e.printStackTrace(); } } }}如果要将 File 转换为 Path , 可以通过 File 类的 toPath() 方法完成 。代码示例如下:
File file = new File("沉默王二.txt");Path path = file.toPath();如果要将 Path 转换为 File , 可以通过 Path 类的 toFile() 方法完成 。代码示例如下:
Path path = Paths.get("沉默王二.txt");File file = path.toFile();02、处理目录
NIO 2.0 新增的 java.nio.file.DirectoryStream<T> 接口可以非常方便地查找目录中的(符合某种规则的)文件 , 比如说我们要查找 chenmo 目录下的 txt 后缀的文件 , 代码示例如下:
// 相对路径Path dir = Paths.get("chenmo");try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.txt")) { for (Path entry : stream) { System.out.println(entry.getFileName()); }} catch (IOException e) { e.printStackTrace();}1)Files.newDirectoryStream(Path dir, String glob) 会返回一个过滤后的 DirectoryStream( 目录流 , ) , 第一个参数为目录 , 第二个参数为 glob 表达式 , 比如 *.txt 表示所有 txt 后缀的文件 。
2)由于 DirectoryStream 继承了 Closeable 接口 , 所以它可以配合 try-with-resources 语法写出更安全的代码 , 目录流会自动调用 close 方法关闭流 , 释放与流相关的资源 , 不需要再通过 finally 进行主动关闭 。
3)DirectoryStream 被称为目录流 , 允许方便地使用 for-each 结构来遍历目录 。
03、处理目录树
目录树意味着一个目录里既有文件也有子目录 , 也可能都没有 , 也可能有其一 。NIO 2.0 可以很方便地遍历一颗目录树 , 并操作符合条件的文件;这其中关键的一个方法就是 Files 类的 walkFileTree , 其定义如下:
public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor) throws IOException { return walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor); }
推荐阅读
- 学习JAVA的十二大步骤,值得你借鉴
- Java开发者必备的9个网站
- 如何更好的使用JAVA线程池
- Java秒杀系统实战系列:商品秒杀代码实战
- Java NIO与I/O的区别到底在哪?缓冲区是什么?
- Java中BIO,NIO,AIO的理解
- 你们说的抖音效果是怎样实现的!程序员:java面前都不是事
- Java的两种跳转语句
- Java程序员必备——Tomcat配置技巧Top10
- Java程序员必备的一些流程图