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. UINavigationController + UIScrollView组合,视图尺寸的设置探秘(二)

    承接上文,我想把view布局修改为如下模式,让ScrollView长在NavigationBar的下方,这总不会有遮挡的问题了吧: story board内容如下,主要是右侧视图蓝色区域添加了Scro ...

  2. day01.2-计算机网络协议

    注:本文摘自林海峰老师的博客,作为个人学习笔记,日后方便阅读,原文详见链接www.cnblogs.com/linhaifeng/articles/5937962.html 一.  ISO协议     ...

  3. 容器编排之Kubernetes1.7.6安装与配置

    kubernetes官网的安装教程是采用kubeadm init的方式,但是在生产环境当中,可能需要独自手动安装k8s,本文采用源码安装的方式,一步步搭建k8s的master节点和node节点. 系统 ...

  4. 502. IPO

    Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Cap ...

  5. 转载黑客是如何黑到你手机的?绝对涨姿势,一位黑客的Wi-Fi入侵实录!

        声明:这是一虚构的故事,因此对图片均进行了模糊化处理.内容整理自网络! 故事的主人公小黑是一名从事IT相关工作的技术宅男.五一长假来临,宅在家中的他相当无聊,打开手机上的Wi-Fi模块,发现附 ...

  6. 转载 【Linux】Linux中常用操作命令

    [Linux]Linux中常用操作命令     https://www.cnblogs.com/laov/p/3541414.html#vim   Linux简介及Ubuntu安装 常见指令 系统管理 ...

  7. Unity---Directory目录的删除、存在、创建操作

    使用Directory类要引入命名空间 using  System.IO; Directory类下的三个静态方法. public static void CreateDirectory(string  ...

  8. Burp Suite初探

    Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程. 一.安装部署 需要配置java环境,首先安装java,然后配置 ...

  9. 最长回文串:LeetCode:Longest Palindromic Substring

    class Solution { public: string longestPalindrome(string s) { int length=s.length(); ; ; ][]={false} ...

  10. kuangbin专题十六 KMP&&扩展KMP HDU2609 How many (最小字符串表示法)

    Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell me How man ...