Java NIO系列教程(一)java NIO简介

时间:2022-09-01 00:07:34

这个系列的文章,我们开始玩一玩IO方面的知识,对于IO和NIO,我们经常会接触到,了解他们的基本内容,对于我们的工作会有特别大的帮助。这篇博文我们仅仅是介绍IO和NIO的基本概念,以及一些关键词。

基本概念

IO是主存和外部设备(硬盘、终端和网络)进行数据拷贝的过程。IO是操作系统的底层功能实现,底层通过I/O指令完成对数据的操作。

java标准IO回顾

Java 标准 IO 类库是 io 面向对象的一种抽象。基于本地方法的底层实现,我们无须关注底层实现。InputStream\OutputStream(面向字节流 ) :一次传送一个字节。 Reader\Writer( 面向字符流 ) :一次一个字符。

java NIO简介

Java NIO(New IO Non Blocking IO)是从Java1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。

Sum官方标榜许多的特性,如下:

  • 为所有的原始类型提供 (Buffer) 缓存支持。
  • 字符集编码解码解决方案。
  • Channel :一个新的原始 I/O 抽象。
  • 支持锁和内存映射文件的文件访问接口。
  • 提供多路 (non-bloking) 非阻塞式的高伸缩性网络 I/O 。

看到NIO这么多的优点,是不是有点小激动。继续看一下他们的区别。

Java NIO与IO的主要区别

下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异。

IO NIO
面向流(Stream Oriented) 面向缓冲区(Buffer Oriented)
阻塞IO(Blocking IO) 非阻塞IO(Non Blocking IO)
(无) 选择器(Selectors)

面向流与面向缓冲

NIO与IO之间本质的区别是,IO是面向流的,NIO是面向缓冲区的。IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。

Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

阻塞与非阻塞IO

IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。

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

选择器(Selectors)

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

IO与NIO的区别是很大的,但是他们又有自己的适用范围:

  • NIO允许你用一个单独的线程或几个线程管理很多个channels(网络的或者文件的),代价是程序的处理和处理IO相比更加复杂。如果你需要同时管理成千上万的连接,但是每个连接只发送少量数据,此时NIO更合适。
  • 如果你只有少量的连接但是每个连接都占有很高的带宽,同时发送很多数据,传统的IO会更适合。

通道与缓冲区

Java NIO系统的核心在于:通道(Channel)和缓冲区(Buffer)。

Buffer:表示打开到IO设备(例如:文件、套接字)的连接。

  • 是一块连续的内存块。
  • 是 NIO 数据读或写的中转地。

Channel:

  • 数据的源头或者数据的目的地
  • 用于向 buffer 提供数据或者读取 buffer 数据 ,buffer 对象的唯一接口。
  • 异步 I/O 支持

基本步骤:

若需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区,然后操作缓冲区,对数据进行处理。

Channel与Buffer的关系:
Java NIO系列教程(一)java NIO简介

简而言之,Channel负责传输,Buffer负责存储 。

总结

本篇博文都是基本概念,内容相对比较苦涩,万事开头难。只要开头,下面会顺风顺水。

下篇博文,我们介绍通道Channel,敬请期待。