在NIO.2的文件系统中,Path是一切操作的基础。Path准确来说,代表着文件系统中的位置。可以代表一个目录(也就是通常所说的文件夹),也可以代表一个文件。

在新文件系统中,还有一个不得不说的就是Files。它是一个工具类,但是这个工具类跟打了鸡血一样,强大到不可思议。以前需要写繁重代码或者需要调用第三方类库才能完成的功能,现在只需一行。

下面的代码展示了Path的最基本操作-获取一个Path;并且通过我们得到的Path和强大的工具类Files来创建一个文件或目录

Path dir0 = Paths.get("c:\\test");// 创建一个Path路径;Paths是工具类,用于产生Path
Files.createDirectory(dir0);// 创建单级目录;若已经存在 则抛出异常
Path dir1 = Paths.get("c:\\test\\Hello.java");
Files.createFile(dir1);// 创建文件;若目录没有 则抛出异常
Path dir2 = Paths.get("c:\\test\\Hello\\World");
Files.createDirectories(dir2);// 创建多级目录;若已经存在 不抛出异常

展示完最基础的创建功能后,再展示一点Path的高级功能——遍历目录

遍历目录有两种方式,一种是通过DirectoryStream类来遍历单层目录,另一种就是通过实现FileVisitor接口来递归的遍历目录

重点强调一下这两者的区别。DirectoryStream只能遍历给定的目录下的文件或目录,如果在给定的目录下还有子目录,那么DirectoryStream不会再向下遍历子目录中的内容。而用实现FileVisitor接口的方式,则在给定的目录下若还有子目录,它会接着遍历子目录中的内容(类似于深度优先搜索)

上代码 首先给出的是DirectoryStream的方式

Path dir3 = Paths.get("c:\\test");
// 1.DirectoryStream可以理解成对于Path的Iterable,返回在dir3中符合第二个参数形式的Path集合
// 2.下面用到了一种try-with-resources的写法,该写法是在java1.7中引入的语法糖(极力推荐大家用该写法,因为它可以帮助你正确的关闭资源)
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir3,
"*.java")) {
for (Path entry : stream) {
System.out.println(entry.getFileName());
}
}

再强调一下Files.newDirectoryStream的第二个参数。这种形式是glob表达式,如*.java代表的就是所有以".java"结尾的字符串

下面再说一下,实现FileVisitor接口的方式。这里得用到Files的一个静态方法

Files.walkFileTree(Path start,FileVisitor<? super Path> visitor)

第一眼就感觉好复杂,而且一看walkFileTree的二个参数就不是善茬,要实现它就得实现下面的4个方法

  • FileVisitResult postVisitDirectory(T dir, IOException exc)
  • FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  • FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  • FileVisitResult visitFileFailed(T file, IOException exc)

但好在java1.7已经提供了一个默认实现类SimpleFileVisitor,这样你就可以只用重写你需要的方法了,下面的例子是打印一个目录下所有文件的名称(文件夹的名称不打印)

Path dir3 = Paths.get("c:\\test");
Files.walkFileTree(dir3, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
System.out.println(file.getFileName());
return FileVisitResult.CONTINUE;
}
});

两段困难的代码看完了,咱们再来的简单的。

文件的创建、删除、复制、移动、重命名等操作,都是我们平时常用的操作。以前想写的话,真得下点功夫或者直接找个第三方类库。但是现在时代不同了,有了Files一切如丝般顺滑。看看Files的文档吧,那里有许多你梦遗所求的方法。这里展示几个常用的。

先来一段删除文件或目录的

Path dir4 = Paths.get("c:\\test\\del");
Files.delete(dir4);// 删除文件或文件夹;删除文件夹时,若文件夹中还有文件或文件夹则抛出异常
Files.deleteIfExists(dir4);// 如果存在该文件或文件夹则删除

删除很简单吧,下面让我们来看看复制

复制要考虑的情况就有点多了,复制我们主要用到的方法是

Files.copy(Path source,Path target,CopyOption... options)

前两个参数分别为原位置和目的位置,第三个参数为复制选项。复制选项的意思,说白了就是复制时发生了各种情况时,该如何处理。CopyOption其实也应该是让你写的,但是java中内置了三种方式供你选择,它们分别是:

StandardCopyOption.REPLACE_EXISTING:如果目的路径有同名文件则替换

StandardCopyOption.ATOMIC_MOVE:若失败则回滚

StandardCopyOption.COPY_ATTRIBUTES:把源文件的文件属性一同复制给新文件(readAttributes等方法可以读取文件属性)

给你个例子

Path source = Paths.get("c:\\test\\Hello.java");
Path target = Paths.get("c:\\test\\Hello\\World\\Hello.java");
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

再就说说文件的移动,基本上与复制同理,主要用到的方法是

Files.move(Path source,Path target,CopyOption... options)

同样,也需要复制选项,其实给文件重命名用的也是这招,下面的例子就展示了这点

Path source = Paths.get("c:\\test\\Hello\\World\\Hello.java");
Path target = Paths.get("c:\\test\\Hello\\World\\He.java");
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

下面要介绍的就是我最喜欢的内容了,给你们看两个方法

List<String> Files.readAllLines(Path path)

Files.write(Path path,Iterable<? extends CharSequence> lines,OpenOption... options)

是不是一目了然。对这就是文件的按行读和按行写,用起来真的特别方便。在java1.7之前,我在guava中看见过这些方法,有时候用guava的io其实根本不是为了它的source和sink,而就是为了这几个方法。这两个方法的出现,反映了java的一种新态度,那就是纳谏、虚心。优秀的命名、方便的工具类,这都是以前java官方中所欠缺的,无论是新的Time包还是lamda表达式或是Coin项目,都是向社区学习、吸收优秀的社区资源,都是将开发者的梦想变为现实、方便开发者。

不好意思扯远了。那就直接上代码了

Path source = Paths.get("c:\\test\\Hello\\World\\Ab.java");
Path target = Paths.get("c:\\test\\Hello\\World\\He.java"); //以防乱码最好设置一下文件的编码格式,在StandardCharsets中有很多种内置编码格式
List<String> list = Files.readAllLines(source, StandardCharsets.UTF_8);
for (String s : list) {
System.out.println(s);
}
//在StandardOpenOption中有很多种内置文件打开方式可供选择
Files.write(target, list, StandardCharsets.UTF_8,StandardOpenOption.WRITE);

整个NIO.2中的新文件系统的主要内容,也就基本这么多(文件属性这块没太说,想学的自己找找资料吧)最后咱们来的略显高端的就是文件系统的监测;主要用到的类是java.nio.file.WatchService,该类在注册后,一直监控文件或目录的变化,若有相应的变化发生,就返回一个事件。这在很多地方都是有用的,而且这个类性能不错

try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
Path dir = Paths.get("c:\\test");
WatchKey key = dir.register(watcher,
StandardWatchEventKinds.ENTRY_DELETE);
for (;;) {
key = watcher.take();
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println(event.kind());
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
}

关于NIO.2中的新文件系统就聊这么多,有什么问题欢迎讨论,若有什么错误,望不吝赐教(赶紧告诉我,我好改,改晚了耽误其他人)

Java NIO教程 文件系统的更多相关文章

  1. Java NIO教程 目录

    "Java NIO系列教程" 是笔者hans为NIO的初学者编写的一份入门教程,想仔细学习的同学可以按照顺序去阅读.由于我学的也不是特别的精,所以错误.疏漏在所难免,希望同学们指正 ...

  2. 海纳百川而来的一篇相当全面的Java NIO教程

    目录 零.NIO包 一.Java NIO Channel通道 Channel的实现(Channel Implementations) Channel的基础示例(Basic Channel Exampl ...

  3. Java NIO教程 前言

    阅读本文前,建议你先了解 旧I/O NIO 是 New I/O 的缩写,要了解它真正的内涵,需要掌握的知识还是比较多的.我努力在这几篇笔记里,勾勒出整个io的面貌.为大家的深入学习铺路. I/O简史 ...

  4. Java NIO 教程

    Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API.本系列教程将有助于你学习和理解Java NIO. Java NIO提供了与 ...

  5. Java NIO教程 MappedByteBuffer

    之前跟大家说过,要讲MappedByteBuffer,现在我来履行承诺了. 首先从大体上讲一下MappedByteBuffer究竟是什么.从继承结构上来讲,MappedByteBuffer继承自Byt ...

  6. [翻译] java NIO 教程---介绍

    原文地址:http://tutorials.jenkov.com/java-nio/index.html Java NIO(new IO)是从java1.4之后的对IO API的另一种选择,即对标准j ...

  7. [转载] Java NIO教程

    转载自并发编程网 – ifeve.com http://ifeve.com/java-nio-all/ 关于通道(Channels).缓冲区(Buffers).选择器(Selectors)的故事. 从 ...

  8. Java NIO教程 Channel

    Channel是一个连接到数据源的通道.程序不能直接用Channel中的数据,必须让Channel与BtyeBuffer交互数据,才能使用Buffer中的数据. 我们用FileChannel作为引子, ...

  9. Java NIO教程 Selector

    这次我们开讲非阻塞I/O中的Selector,它需要配合非阻塞的TCP和UDP来使用.首先我们先简单讲一下TCP和UDP的非阻塞通道. 非阻塞I/O通道 在上代码前我们先讲解一些最基本的知识.TCP和 ...

随机推荐

  1. SQL数据库的十条命令

    --(1)查询每个总学时数 select GradeId,SUM(classHour) from subject group by GradeId order by(SUM(classHour)) - ...

  2. 配置recovery_min_apply_delay后重启standby节点报错:psql: FATAL: the database system is starting up

    环境: pg版本:PostgreSQL 9.4.4 on x86_64 系统版本:CentOS release 6.6 linux内核版本:2.6.32-504.8.1.el6.x86_64 今天测试 ...

  3. selenium下拉框选择

    下拉框结构如下,我需要选择的是new: html为: <select id="condition_type" name="condition_type" ...

  4. mybatis 使用记录

    首先,贴一个好文.把mybatis中的<if></if>的条件扒到源码分析了一遍.PS:目前还看不懂... http://cheng-xinwei.iteye.com/blog ...

  5. The error occurred while setting parameters--索引 3 超出范围 sqlserver2008

    这个问题不是jar包冲突,是表的问题,表里的ID设置成自动增加1,就可以了!

  6. Spring webapp - shutting down threads on Application stop

    显示使用线程池Executors,必须执行 pool.shutdown() 否则会存在线程池泄露: http://stackoverflow.com/questions/22650569/spring ...

  7. SoftEnther VPN 在Window的使用

    1.首先下载SoftEnther VPN Client 下载地址 2. 下载后,执行vpngate-client-×××.exe 文件 选择安装一个软件部分: SoftEnther VPN Clien ...

  8. SQL 表 和字符串 互转 (行列互转)

    -- 表转字符串 )) ,,'') --字符串转表 ),)) ,) )) AS BEGIN DECLARE @StartIndex INT --开始查找的位置 DECLARE @FindIndex I ...

  9. grunt集成自动启动

    Grunt可以执行像压缩, 编译, 单元测试, 代码检查以及打包发布的任务. 本文介绍使用Grunt实现nodejs程序自启动功能. 目录: Grunt介绍 Grunt安装 Grunt使用 Grunt ...

  10. 【Linux】浅谈I/O模型

    关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer. 如下图所示: ...