NIO2
I/O发展历史
Java1.0-1.3
在Java的早期版本中,没有完整的I/O支持,在开发过程中需要解决以下问题:1)没有数据缓冲区或者NIO的通道概念,需要编程人员处理底层细节。2)I/O是受阻塞的。3)不支持正则表达式,数据处理困难。

Java1.4引入NIO
Java 1.4阶段,开始支持非阻塞I/O。帮助开发人员提供更快/更可靠的I/O解决方案。主要引入有2次:1)Java 1.4中引入非阻塞I/O。2)在Java 7中对非阻塞I/O进行修改。但是还存在局限性:1)不同平台中对文件名的处理不一致。2)没有统一的文件属性模式。3)遍历目录困难。4)不能使用平台/操作系统的特征。5)不支持文件系统的非阻塞操作。

I/O – NIO.2
为了解决NIO的局限,同时为了支持现代硬件和软件的I/O新规范。引入了NIO.2 API。主要特性为:1)一个能批量获取文件属性的文件系统接口,取消和特定文件系统相关的API,还有一个用于引入标准文件系统实现的服务提供者接口。2)引入一个套接字和文件都能够进行异步I/O操作的API。3)完成JSR-51中定义的套接字——通道功能。

Path
在NIO.2的文件I/O中,Path是必须掌握的关键类之一。Path是一个抽象的构造,在创建和处理Path的时候不需要马上绑定对应的物理位置。Path通常代表文件系统中的位置,例如:c://path….等路径地址。

Path并不仅限于传统的文件系统,它也能表示zip或jar这样的文件系统。

创建Path
以下方法都可以简单的创建Path类。

@Test
public void test1() {
Path path = Paths.get("D:\\path");
Path path1 = Paths.get("D:", "path");
Path path2 = FileSystems.getDefault().getPath("D:\\path");
}

从Path中获取信息
这只是简单的罗列下Path中的部分方法,详细的可以去看API。

@Test
public void test2() {
Path path = Paths.get("D:\\path");
System.out.println("文件名:" + path.getFileName());//文件或文件夹名称
System.out.println("路径中名称元素的数量:" + path.getNameCount());//文件路径级别
System.out.println("父目录路径:" + path.getParent());//父路径
System.out.println("ROOT:" + path.getRoot());//根路径
}

Path与File的转换
虽然Path可以替代File,但是系统中难免有遗留代码需要维护,所有API提供了Path和File的转换。

@Test
public void test2() {
Path path = Paths.get("D:\\path");
File file = path.toFile();
Path path1 = file.toPath();
}

处理目录和目录树
遍历目录是Java7引入瞩目的新特性。新加入的java.nio.file.DirectoryStream<T>接口和它的实现类系统了很多功能:1)循环遍历目录中的子项,比如查找目录中的文件。2)用glob表达式匹配目录子项和基于MIME的内容检测(例如text/xml)。3)walkFileTree方法实现递归移动/复制和删除操作。

在目录中查找文件
例如在文件夹中罗列出.properties后缀文件。在以前需要遍历然后比较文件的后缀名称。文件使用glob表达式过滤,看谷歌具体的教程,现在请看:

@Test
public void test2() {
Path path = Paths.get("D:\\path");
try (
DirectoryStream<Path> paths = Files.newDirectoryStream(path, "*.properties");
) {
for (Path p : paths ) {
System.out.println("file name = " + p.getFileName());
}
} catch (IOException e) { }
}

遍历目录树
Java7支持整个目录树(子目录也会遍历)的遍历操作。这样可以简单的对子目录查找并执行操作。Files.walkFileTree(Path startingDir, FileVisitor<? Super Path> vistor);是最关键的方法。FileVisitor需要实现4个方法(Java 8),但是API已经提供了默认实现类SimpleFileVisitor<T>。

@Test
public void test3() throws IOException {
Path path = Paths.get("D:\\path");
Files.walkFileTree(path, new FindXMLVisitor());
} class FindXMLVisitor extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (file.toString().endsWith(".xml")) {
System.out.println(file.getFileName());
}
return FileVisitResult.CONTINUE;
}
}

NIO.2的文件系统I/O
在NIO.2对文件系统的移动文件/修改文件属性等都有很好的改善和支持。主要由Files类提供。

创建和删除文件

@Test
public void test4() throws IOException {
Path path = Paths.get("D:\\path\\create.xml");
//Files.createFile(path);
Files.delete(path);
}

复制和移动文件

@Test
public void test4() throws IOException {
Path source = Paths.get("D:\\path\\123.txt");
Path target = Paths.get("D:\\path\\456.txt");
//第三个参数表示复制时候的属性,这个是覆盖文件,如果文件已存在则覆盖
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
@Test
public void test4() throws IOException {
Path source = Paths.get("D:\\path\\123.txt");
Path target = Paths.get("D:\\path\\backup\\123.txt");
//第三个参数表示复制时候的属性,这个是覆盖文件,如果文件已存在则覆盖
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
}

快速读写数据
Java7中可以直接使用带有缓冲区的读取器和写入器或输入输出流操作文件。

@Test
public void test5() {
Path readers = Paths.get("D:\\path\\123.txt");
Path writes = Paths.get("D:\\path\\456.txt");
try (BufferedReader reader = Files.newBufferedReader(readers,StandardCharsets.UTF_8);
BufferedWriter writer = Files.newBufferedWriter(writes, StandardCharsets.UTF_8)) {
//读取
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
//写入
writer.write("write");
} catch (IOException e) {
e.printStackTrace();
}
}

一次读取全部,如果文件内容比较大,建议不要这样读取,因为内存容易泄露

@Test
public void test5() {
Path readers = Paths.get("D:\\path\\123.txt");
try {
List<String> lines = Files.readAllLines(readers,StandardCharsets.UTF_8);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}

异步I/O操作
异步IO其实只是在进行读写操作的时候允许进行其它操作处理。

将来式
将来式只是使用java.util.concurrent.Future接口来,在使用该接口的get方法后,如果处理完毕立即返回数据,如果没有则阻塞。

@Test
public void test6() throws IOException, ExecutionException, InterruptedException {
Path readers = Paths.get("D:\\path\\123.txt");
//异步打开文件
AsynchronousFileChannel channel = AsynchronousFileChannel.open(readers);
ByteBuffer buffer = ByteBuffer.allocate(100_000);//读取100 000字节
Future<Integer> result = channel.read(buffer, );//读取
//处理其它事情
System.out.println("处理其它事情");
Integer integer = result.get();//获取结果,如果已经执行完立即返回,否则阻塞到执行完毕
}

回调式
回调式通过处理完毕后执行回调函数的方法去通知。

@Test
public void test7() throws IOException {
Path readers = Paths.get("D:\\path\\123.txt");
//异步打开文件
AsynchronousFileChannel channel = AsynchronousFileChannel.open(readers);
ByteBuffer buffer = ByteBuffer.allocate(100_000);//读取100 000字节
channel.read(buffer, , buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("执行完毕后执行这里的方法");
} @Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("失败后执行这里的方法");
}
});
}

---------------------
原文:https://blog.csdn.net/sinat_32366329/article/details/80564338

什么是NIO2的更多相关文章

  1. Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端

    Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端用AsynchronousServerS ...

  2. BIO,NIO,AIO(NIO2)的理解

    写在前面,这里所说的IO主要是强调的网络IO 1.BIO(同步并阻塞) 客户端一个请求对应一个线程.客户端上来一个请求(最开始的连接以及后续的IO请求),服务端新建一个线程去处理这个请求,由于线程总数 ...

  3. java7 NIO2 watching service API

    java7 NIO2新增了文件系统的相关事件处理API,为目录,文件新增修改删除等事件添加事件处理. package reyo.sdk.utils.file; import java.io.IOExc ...

  4. Java基础——NIO(二)非阻塞式网络通信与NIO2新增类库

    一.NIO非阻塞式网络通信 1.阻塞与非阻塞的概念  传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write() 时,该线程被阻塞,直到有一些数据被读取或写入,该线程在 ...

  5. Java IO------------------BIO(同步阻塞)、NIO1.0(多路复用)、NIO2.0(AIO,非阻塞)

    1. BIO JDK5之前, JDK的IO模式只有BIO(同步阻塞)问题: 因为阻塞的存在, 需对每个请求开启一个线程. 过多的线程切换影响操作系统性能解决: 使用线程池, 处理不过来的放入队列, 再 ...

  6. Java NIO2 File API介绍

    Introduction to the Java NIO2 File API GitHub NIO2中的文件API是Java 7附带的Java平台的主要新功能之一,特别是新的文件系统API的一个子集以 ...

  7. Java NIO2:缓冲区

    什么是缓冲区 一个缓冲区对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里数据可被存储并在之后用于检索.缓冲区像前篇文章讨论的那样被写满和释放,对于每个非布尔原始数据类型都有一个缓 ...

  8. java nio2

    Buffer的基本用法 使用Buffer读写数据一般遵循以下四个步骤: 写入数据到Buffer 调用flip()方法 从Buffer中读取数据 调用clear()方法或者compact()方法 当向b ...

  9. 说说nio2

    利不百不变法,功不十不易器 为什么会出现nio,之前的io有什么问题? 请先看 说说nio1 nio类图例如以下 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...

随机推荐

  1. 【转】windows server 2012 R2搭建IIS服务器

    源地址:http://blog.csdn.net/microsoft_wu/article/details/46521017

  2. [USACO5.4]奶牛的电信Telecowmunication 最小割

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  3. Qt 学习之路 2(18):事件

    Home / Qt 学习之路 2 / Qt 学习之路 2(18):事件 Qt 学习之路 2(18):事件  豆子  2012年9月27日  Qt 学习之路 2  60条评论 事件(event)是由系统 ...

  4. 树莓派使用 HLS 实现视频流直播

    说明 这次介绍一下基于上一篇文章"树莓派编译安装 FFmpeg "的应用,即 HLS 视频流直播.原理是 FFmpeg 将 USB 摄像头的原始视频流压缩为 H.264 视频流,然 ...

  5. Android 远程连接数据库。。。。。

    本来是 6.0.6  换成mysql 5.1.14 驱动ok.... 将方法 放在 new Thread() 解决..... 只能在主线程绘制ui.... 解决办法...子Thread 获取数据后,将 ...

  6. mysql 备份时间 %date~0,4%和 %time~0,2%等用法详解

    比如在windowscmd命令行窗口执行date命令后这个环境变量的值为 当前日期:2014-09-01 星期六 或2014/09/01 周六 那么如下的各个操作的意义如下:%date:~0,4% 表 ...

  7. Kibana6.x.x源码分析--启动时basePath

    每次启动Kibana时,发现URL都会随机的生成三位字母,比如:[http://localhost:5601/abc/][http://localhost:5601/dzf/]等等,那么这些随机的字符 ...

  8. Applese 涂颜色(python解法)

    链接:https://ac.nowcoder.com/acm/contest/330/E 来源:牛客网 题目描述 精通程序设计的 Applese 叕写了一个游戏. 在这个游戏中,有一个 n 行 m 列 ...

  9. 关于django的模板层

    你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now = datet ...

  10. day19 MRO C3算法 super()

    1. MRO(Method Resolution Order):方法解析顺序,主要用于在多继承时判断调的属性的路径(来自于哪个类). 1.Python语言包含了很多优秀的特性,其中多重继承就是其中之一 ...