Java NIO教程 前言

阅读本文前,建议你先了解 旧I/O
NIO 是 New I/O 的缩写,要了解它真正的内涵,须要掌握的知识仍是比较多的。我努力在这几篇笔记里,勾勒出整个io的面貌。为你们的深刻学习铺路。java

I/O简史

想理解I/O的所有,java的I/O历史是必需要了解的。java的I/O历史也从一个侧面反应了java的发展史。正则表达式

JDK1.0-1.3

在这个时期的java中,基本上能够说没有完整的I/O支持。由于这一时期的java I/O操做是阻塞的,因此I/O效率是较为底下的,基本上想要有比较好的I/O解决方案,基本靠本身。这时期java在服务器端一直没有获得重用,和糟糕的I/O效率是有很大的关系的。不但I/O弄的很差,并且一系列周边措施都没弄好。所支持的字符集编码有限,常常要进行手工的编码工做。并且没有正则表达式,处理数据十分困难。缓存

JDK1.4-1.6

2002年发布的java1.4中,非阻塞I/O以JSR-51的身份加入到java语言中。同时字符集的编解码能力大大提高。并且有了基于perl实现的正则表达式类库。同时部分旧I/O底层实现,也用新I/O的方式重写,使得旧I/O的性能也有了提高。终于java在服务器端开始流行了起来。服务器

与此同时,第三方也开始发力。谷歌发布了Guava类库,其中的I/O部分,极大的简化了一些文件的操做和数据的传输。同时Trustin Lee领导编写的nio框架netty与mina也广为流传开来,这对java nio的发展业是有着极大的推进力的。网络

JDK1.7至今

随着JSR-203的推出,是咱们在java1.7中见到了NIO2。它为咱们提供了必非阻塞更增强大的异步I/O操做能力,同时提供了一系列极为方便的对文件系统和文件属性进行操做的API。以及更增强大的网络I/O框架

I/O区别

阻塞I/O、非阻塞I/O、异步I/O之间到底有什么区别?为何每一次的进步,都会促使java I/O能力的极大提高?咱们举一个种菜游戏的例子。异步

假若有一个种菜游戏(就跟以前的QQ农场相似),在玩家种菜之后,必须一直呆在那个网页上,看着菜成熟,才能够收菜。这是极其浪费时间的,用户体验也必定不会好。这个游戏后来进行了改版,玩家种菜以后不用再一直停留在那个网页上了,只是须要时不时来看一遍,若是某一次查看时发现菜成熟了,就能够收菜了。固然,用户体验极大的提高了,用户所浪费的时间也减小了,可是为了更加提高用户体验,游戏又进行了改版。玩家种菜以后,不用再查看菜是否成熟了,等到菜成熟后,该游戏会自动给用户发送一个通知,告诉他,菜已成熟、赶忙来收。这样用户的基本上不再用浪费时间了。性能

刚刚例子中的三个游戏版本,表明了三种I/O。阻塞I/O:在数据没有读写完成以前,CPU不能够进行下一步操做,这样CPU只好眼睁睁的在那里傻等。非阻塞I/O:在数据没有读写完成以前,CPU能够离开,只须要每隔一段时间询问一次。异步I/O:在数据没有读写完成以前,CPU能够离开也不用时不时的关心一下I/O,在数据读写完成时,主动通知CPU。三种I/O之间的效率,高低立判。学习

新I/O

我们以java1.4所提出的非阻塞I/O,为切入点,开始了解全貌。编码

  • Channels
  • Buffers
  • Selectors

这三个类构成了非阻塞I/O的核心API。

Buffer译为缓存区,它是一块能够存储数据的内存。Channel有点像流,但它可读可写、从本地I/O到网络I/O均可以,绝大多数NIO都从一个Channel开始的,数据能够从Channel读到Buffer中,也能够从Buffer 写到Channel中。
Channel和Buffer交互
非阻塞I/O中,CPU能够在数据没有读写完成以前离开,只须要每隔一段时间询问一次。询问数据是否读写完成,须要的CPU能力是极小的,但若是CPU常常切换任务所须要的保留现场和恢复现场的时间是较大的。因此能够就用一个线程来询问数据是否准备好。一个线程在多个通道内询问数据是否准备好,就须要管理多个通道的方式,这就是
Selector
使用Selector,得向Selector注册Channel,而后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就能够处理这些事件。

说了这么多,咱们该从什么地方开始呢? 我们从java7的新文件系统开始吧

相关文章
相关标签/搜索