在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. ios/iphone手机请求微信用户头像错位BUG及解决方法

    转:http://www.jslover.com/code/527.html ios/iphone手机请求微信用户头像错位BUG及解决方法 发布时间:2014-12-01 16:37:01 评论数:0 ...

  2. [BZOJ 3209]花神的数论题

    一道简单的数位 dp 题 但是脑子里只有 __builtin_popcountll 了呢(自重) 看完题解后很快就理解了,而且有一种这么简单的题居然没想到做法真是不应该唉~的感觉 用 f[i] 表示 ...

  3. 论文笔记之:Deep Attention Recurrent Q-Network

    Deep Attention Recurrent Q-Network 5vision groups  摘要:本文将 DQN 引入了 Attention 机制,使得学习更具有方向性和指导性.(前段时间做 ...

  4. 需求文档2_The Battle of Polytopia

    需求文档 ------------------------------------- 1. 游戏详细分析 The Battle of Polytopia简要介绍 探索型.策略型的对战塔防游戏,回合制. ...

  5. Lucene/Solr搜索引擎开发笔记 - 第2章 Solr安装与部署(Tomcat篇)

    一.安装环境 图1-1 Tomcat和Solr的版本 我本机目前使用的Java版本为JDK 1.8,因为Solr 4.9要求Java版本为1.7+,请注意. 二.Solr部署到Tomcat流程 图1- ...

  6. springfox.documentation.spi.DocumentationType配置示例

    Java Code Examples for springfox.documentation.spi.DocumentationType The following are top voted exa ...

  7. H5 App开发用WeX5垃圾 试用一周,我果断放弃了wex5

    上个月,和朋友一起参加wex5的分享会,因为对cordova有些了解,始终不相信wex5的广告.五一假期,小试一下,果然不出我所料,有不少坑. 想下载IDE,竟然有1.7G,虽然现在网速快但是文件太大 ...

  8. MapReduce、Hbase接口API实践

    读取hdfs中文件并做处理,取出卡号,通过卡号连接hbase查询出对应客户号,写入redis,因为不用输出,所以不调用context.write方法,整个操作在一个map中便可完成 protected ...

  9. 在Spring的bean中注入HttpServletRequest解密

    我们可以在Spring的bean中轻松的注入HttpServletRequest,使用@Autowired HttpServletRequest request;就可以了. 但是,为什么我们可以直接这 ...

  10. 炉石复盘 宇宙法vs复活牧 [20161130]

    选宇宙法完成使用50个法师职业牌的任务,遇到一个复活牧泰兰德. 前中期下怪,解场.虽然宇宙法偏娱乐,但牧师节奏也比较慢,因此血线一度降到10血以下,但仍然不惧怕牧师斩杀. 9费牧师拍下伊瑟拉,解不掉, ...