Java NIO:NIO概述

转载 2018年03月06日 00:00:00

上一篇:Java NIO:浅析I/O模型


  在上一篇博文中讲述了几种IO模型,现在我们开始进入Java NIO编程主题。NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题。本文下面分别从Java NIO的几个基础概念介绍起。

  以下是本文的目录大纲:

  一.NIO中的几个基础概念

  二.Channel

  三.Buffer

  四.Selector

  若有不正之处,请多多谅解并欢迎批评指正。

一.NIO中的几个基础概念

  在NIO中有几个比较关键的概念:Channel(通道),Buffer(缓冲区),Selector(选择器)。

  首先从Channel说起吧,通道,顾名思义,就是通向什么的道路,为某个提供了渠道。在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:

public class Test {
   public static void main(String[] args) throws IOException  {
       File file = new File("data.txt");
       InputStream inputStream = new FileInputStream(file);
       byte[] bytes = new byte[1024];
       inputStream.read(bytes);
       inputStream.close();
   }  
}

   这里的InputStream实际上就是为读取文件提供一个通道的。

  因此可以将NIO 中的Channel同传统IO中的Stream来类比,但是要注意,传统IO中,Stream是单向的,比如InputStream只能进行读取操作,OutputStream只能进行写操作。而Channel是双向的,既可用来进行读操作,又可用来进行写操作。

  Buffer(缓冲区),是NIO中非常重要的一个东西,在NIO中所有数据的读和写都离不开Buffer。比如上面的一段代码中,读取的数据时放在byte数组当中,而在NIO中,读取的数据只能放在Buffer中。同样地,写入数据也是先写入到Buffer中。

  下面介绍一下NIO中最核心的一个东西:Selector。可以说它是NIO中最关键的一个部分,Selector的作用就是用来轮询每个注册的Channel,一旦发现Channel有注册的事件发生,便获取事件然后进行处理。

  比如看下面的这个例子:

640

  用单线程处理一个Selector,然后通过Selector.select()方法来获取到达事件,在获取了到达事件之后,就可以逐个地对这些事件进行响应处理。

二.Channel

  在前面已经提到,Channel和传统IO中的Stream很相似。虽然很相似,但是有很大的区别,主要区别为:通道是双向的,通过一个Channel既可以进行读,也可以进行写;而Stream只能进行单向操作,通过一个Stream只能进行读或者写;

  以下是常用的几种通道:

  • FileChannel

  • SocketChanel

  • ServerSocketChannel

  • DatagramChannel

  通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。

  下面给出通过FileChannel来向文件中写入数据的一个例子:

public class Test {
   public static void main(String[] args) throws IOException  {
       File file = new File("data.txt");
       FileOutputStream outputStream = new FileOutputStream(file);
       FileChannel channel = outputStream.getChannel();
       ByteBuffer buffer = ByteBuffer.allocate(1024);
       String string = "java nio";
       buffer.put(string.getBytes());
       buffer.flip();     //此处必须要调用buffer的flip方法
       channel.write(buffer);
       channel.close();
       outputStream.close();
   }  
}

   通过上面的程序会向工程目录下的data.txt文件写入字符串"java nio",注意在调用channel的write方法之前必须调用buffer的flip方法,否则无法正确写入内容,至于具体原因将在下篇博文中具体讲述Buffer的用法时阐述。

三.Buffer

  Buffer,故名思意,缓冲区,实际上是一个容器,是一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读取或写入的数据都必须经由Buffer。具体看下面这张图就理解了:

640

  上面的图描述了从一个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送数据时,必须先将数据存入Buffer中,然后将Buffer中的内容写入通道。服务端这边接收数据必须通过Channel将数据读入到Buffer中,然后再从Buffer中取出数据来处理。

  在NIO中,Buffer是一个顶层父类,它是一个抽象类,常用的Buffer的子类有:

  • ByteBuffer

  • IntBuffer

  • CharBuffer

  • LongBuffer

  • DoubleBuffer

  • FloatBuffer

  • ShortBuffer

  如果是对于文件读写,上面几种Buffer都可能会用到。但是对于网络读写来说,用的最多的是ByteBuffer。

  关于Buffer的具体使用以及它的limit、posiion和capacity这几个属性的理解在下一篇文章中讲述。

四.Selector

  Selector类是NIO的核心类,Selector能够检测多个注册的通道上是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间的上下文切换导致的开销。

  与Selector有关的一个关键类是SelectionKey,一个SelectionKey表示一个到达的事件,这2个类构成了服务端处理业务的关键逻辑。

  关于Selector类的具体使用将在后续文章中阐述。

  • 原文:http://www.cnblogs.com/dolphin0520/p/3919162.html

640?

Java团长

微信号:javatuanzhang

每日分享Java技术干货

640?

长按识别二维码

《Java之IO , BIO , NIO , AIO 知多少?》

-
  • 1970年01月01日 08:00

Java NIO系列教程(一) Java NIO 概述

  • 2016年11月28日 22:01
  • 262KB
  • 下载

JavaNIO chm帮助文档

  • 2017年10月09日 17:20
  • 163KB
  • 下载

Java NIO(1)概述

NIO概述NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发...
  • DoUUnderstand
  • DoUUnderstand
  • 2017-04-18 11:43:01
  • 242

java NIO和java并发编程的书籍

  • 2011年11月13日 22:58
  • 3.87MB
  • 下载

JAVA NIO 实现网络编程

  • 2011年09月27日 01:25
  • 188KB
  • 下载

Java NIO编写Socket服务器的一个例子

Java中编写Socket服务器,通常有一下几种模式: 1. 一个链接一个线程;优点:程序编写简单; 缺点:如果链接非常多,分批的线程会非常多,机器可能资源耗尽而崩溃。 2.把每一个新链接,交接给一个...
  • xidianliuy
  • xidianliuy
  • 2016-06-08 14:02:18
  • 5148

说说java NIO的一些个人总结

首先了解下所谓的java nio是个什么东西! IO是靠字符或字节进行传输,比较慢! 而NIO是靠块, 也就相当于一个Buffer, 一块一块 的传输, 速度较快 ! 同时加入了多线程 的控制...
  • Truong
  • Truong
  • 2017-07-02 21:23:10
  • 5723

java nio原理和它的优点

要想讲清楚nio的原理和它的优点得先清楚Java应用程序的文件读写原理和虚拟内存的原理。Java文件读取原理可参见如下图: 当应用程序需要读取文件的时候,内核首先通过DMA技术将文件内容从磁...
  • u012684933
  • u012684933
  • 2015-11-06 15:20:14
  • 8216

Java NIO-非阻塞通信

相对于非阻塞通信的复杂性,通常客户端并不需要使用非阻塞通信以提高性能,故这里只有服务端使用非阻塞通信方式实现...
  • a19881029
  • a19881029
  • 2013-10-17 10:31:05
  • 4809
收藏助手
不良信息举报
您举报文章:Java NIO:NIO概述
举报原因:
原因补充:

(最多只允许输入30个字)