NIO 定义

即新IO,在JDK1.4的java.nio.*包中引入,其目的在于提高速度。

在Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据,面向流的I/O速度非常慢,而在Java 1.4中推出了NIO,这是一个面向块的I/O系统,系统以块的方式处理处理,每一个操作在一步中产生或者消费一个数据库,按块处理要比按字节处理数据快的多。

速度的提高来自于所使用的结构更接近于操作系统执行IO的方式:通道和缓冲期。我们可以把它想象成一个煤矿,通道是一个包含煤层(数据)的矿藏,而缓冲器则是派送到矿藏的卡车。卡车满载煤炭而归,我们再从卡车上获得煤炭。也就说,我们并没有直接好通道交互,我们只和缓冲区交互。

缓冲区(Buffer)

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。,在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的; 在写入数据时,它也是写入到缓冲区中的;任何时候访问 NIO 中的数据,都是将它放到缓冲区中。而在面向流I/O系统中,所有数据都是直接写入或者直接将数据读取到Stream对象中。

在NIO中,所有的缓冲区类型都继承于抽象类Buffer,最常用的就是ByteBuffer,对于Java中的基本类型,基本都有一个具体Buffer类型与之相对应,它们之间的继承关系如下图所示:

Buffer基本用法

使用Buffer读写数据一般遵循以下四个步骤:

  1. 写入数据到Buffer
  2. 调用flip()方法
  3. 从Buffer中读取数据
  4. 调用clear()方法或者compact()方法

当向buffer写入数据时,buffer会记录下写了多少数据。一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式。在读模式下,可以读取之前写入到buffer的所有数据。

一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

通道(Channel)

通道是一个对象,通过它可以读取和写入数据,当然了所有数据都通过Buffer对象来处理。我们永远不会将字节直接写入通道中,相反是将数据写入包含一个或者多个字节的缓冲区。同样不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

通道类似流,但又有些不同:

  • 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
  • 通道可以异步读写
  • 通道中数据总要先读到Buffer,或者从一个Buffer写入

这个图看着好混乱,那我们讲几个比较重要的通道:

  • FileChannel : 从文件中读写数据。
  • DatagramChannel :通过UDP读写网络中的数据。
  • SocketChannel :通过TCP读写网络中的数据。
  • ServerSocketChannel: 监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

Channel基本用法

  1. 获取Channel
  2. 创建Buffer
  3. 将数据从Channel读取到Buffer

为了说明,下面举个读文件的例子。

    public static void main(String[] args) {try {FileInputStream fin = new FileInputStream("test.txt");// get channelFileChannel fc = fin.getChannel();// bufferByteBuffer buffer = ByteBuffer.allocate(1024);//read data to bufferfc.read(buffer);buffer.flip();while(buffer.remaining()>0){byte b = buffer.get();System.out.print((char)b);}fin.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

阻塞IO(常规IO) VS 非阻塞IO(NIO)

  • Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。
  • Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情;非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

所以这就引入一个概念,选择器

选择器(Selectors)

Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。

你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

使用

要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。

转载于:https://www.cnblogs.com/tina-smile/p/5245326.html

java_IO流之 NIO相关推荐

  1. JAVA_IO流四大家族(2)

    JAVA_IO流四大家族体系: JAVA_IO流四大家族(1) JAVA_IO流四大家族(2) 文章目录 JAVA_IO流四大家族体系: JAVA_IO流四大家族(1) JAVA_IO流四大家族(2) ...

  2. JAVA_IO流四大家族(1)

    JAVA_IO四大家族体系: JAVA_IO流四大家族(1) JAVA_IO流四大家族(2) 文章目录 JAVA_IO四大家族体系: JAVA_IO流四大家族(1) JAVA_IO流四大家族(2) 常 ...

  3. Java_IO流(精讲)包含练习题及答案

    Java_IO流(精讲)包含练习题及答案--建议收藏 包含常用的所有属性与函数的示例,并且对[字符流][字节流]分别做的[读写]操作示例. 目录 1.Java Io流的概念 按照流的流向分,可以分为输 ...

  4. Java_IO流-IO流

    文章目录 2 file类 2.1 新建文件夹或文件 2.2 copy1 2.3 copy2 2.4 可以覆盖掉旧文件的copy 4 字节流转字符流读取文件中内容 5 读取Properties文件中的内 ...

  5. Java_IO流_抽象类

    一.   概念 流动,从一端流向另一端,源头与目的地 以程序为中心,程序与 数组/文件/网络连接/数据库, 二.   io流分类 流向:输入流与输出流 数据 :字节楼:二进制,所有文件都可以操作,包括 ...

  6. 第十章:Java_IO流

    Java IO流 1.java.io包下 File类:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源. File file1 = new File("d:\io\ ...

  7. JAVA_IO流的关闭两种方式

    流的关闭 当使用完流后,显示的关闭所有打开的流仍然是一个好习惯.一个被打开的流有可能会用尽系统的资源,这取决于平台和实现.如果没有将流关闭,另一个程序试图打开另一个流时,可能会得到不需要的资源. 从J ...

  8. Java_io流详解(代码)

    目录 创建文件 获取文件信息 目录操作 FileInputStream FileOutputStream 文件拷贝 BufferedReader BufferedWrter BufferedCopy ...

  9. java_IO流之SequenceInputStream合并流的使用

    http://blog.csdn.net/java4found/article/details/8656594

最新文章

  1. 干得累死,并不见得老板就待见你?——来自多位专家的见解
  2. java 反序列化 ysoserial exploit/JRMPClient 原理剖析
  3. TLD(Tracking-Learning-Detection)学习与源码理解之(四)
  4. 致远协同软件手机版让移动办公不再是梦想
  5. shell 脚本从1加到100
  6. 页面加载时间如何影响你的收益?
  7. oracle删除unique key,概述Oracle Unique约束
  8. Java并发编程-volatile关键字介绍
  9. 【笔试】:编程实现C++string 类成员函数
  10. mysql 5.6 利用gtid 同步数据遇到的问题记录
  11. 市场活动课件:SQL Server 索引优化
  12. 华为nova 4e 3月14日发布:麒麟710+3200万前摄
  13. chrome fiddler 重定向 https 请求
  14. html增值税申报表,关于调整增值税纳税申报有关事项的公告
  15. 没有无线网络设备时如何共享无线网络
  16. linux 2.6.32文件系统的dentry父子关系
  17. SQLserver With As 用法
  18. “印象笔记”使用笔记
  19. Coremail2022Q4邮件安全报告:暴力破解骤降,盗号问题有所缓解?
  20. 学生选课系统-学年学期选择器,根据入学年份自动计算当前学期

热门文章

  1. IOS UIPageController
  2. jmeter对oracle压力测试
  3. 相机添加多张图片css布局
  4. Qt QTcpSocket使用总结
  5. ios开发之--UIDocumentInteractionController的使用(实现更多分享服务)
  6. 在gitlab 中使用webhook 实现php 自动部署git 代码
  7. 《Nmap渗透测试指南》—第7章7.8节后台打印机服务漏洞
  8. 《Git权威指南》笔记2
  9. 在VS2012中实现Ext JS的智能提示太简单了
  10. 【转】C# split 几种使用方法