- 1、本文档共17页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Java-NIO-异步流详解
一、基本概念描述
1.1 I/O 简介
I/O 即输入输出,是计算机与外界世界的一个接口。IO 操作的实际主题是操作系统。在
java 编程中,一般使用流的方式来处理IO,所有的IO 都被视作是单个字节的移动,通
过stream 对象一次移动一个字节。流 IO 负责把对象转换为字节,然后再转换为对象。
1.2 什么是 NIO
NIO 即New IO,这个库是在JDK1.4 中才引入的。NIO 和IO 有相同的作用和目的,但
实现方式不同,NIO 主要用到的是块,所以NIO 的效率要比IO 高很多。
在Java API 中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程
NIO。本篇文章重点介绍准输入输出NIO,关于网络编程NIO 请见第二部分。
1.3 流与块的比较
NIO 和IO 最大的区别是数据打包和传输方式。IO 是以流的方式处理数据,而NIO 是以
块的方式处理数据。
面向流的IO 一次一个字节的处理数据,一个输入流产生一个字节,一个输出流就消费
一个字节。为流式数据创建过滤器就变得非常容易,链接几个过滤器,以便对数据进行
处理非常方便而简单,但是面向流的IO 通常处理的很慢。
面向块的IO 系统以块的形式处理数据。每一个操作都在一步中产生或消费一个数据块。
按块要比按流快的多,但面向块的IO 缺少了面向流IO 所具有的有雅兴和简单性。
二、NIO 基础
Buffer 和Channel 是标准NIO 中的核心对象(网络NIO 中还有个Selector 核心对象,
稍后讲解),几乎每一个IO 操作中都会用到它们。
Channel 是对原IO 中流的模拟,任何来源和目的数据都必须通过一个Channel 对象。
一个Buffer 实质上是一个容器对象,发给Channel 的所有对象都必须先放到Buffer 中;
同样的,从Channel 中读取的任何数据都要读到Buffer 中。
2.1 关于 Buffer
Buffer 是一个对象,它包含一些要写入或读出的数据。在NIO 中,数据是放入buffer 对
象的,而在 IO 中,数据是直接写入或者读到 Stream 对象的。应用程序不能直接对
Channel 进行读写操作,而必须通过 Buffer 来进行,即 Channel 是通过 Buffer 来
读写数据的。
在NIO 中,所有的数据都是用Buffer 处理的,它是NIO 读写数据的中转池。Buffer 实
质上是一个数组,通常是一个字节数组,但也可以是其他类型的数组。但一个缓冲区不
仅仅是一个数组,重要的是它提供了对数据的结构化访问,而且还可以跟踪系统的读写
进程。
使用 Buffer 读写数据一般遵循以下四个步骤:
1. 写入数据到 Buffer;
2. 调用 flip() 方法;
3. 从 Buffer 中读取数据;
4. 调用 clear() 方法或者 compact() 方法。
当向 Buffer 写入数据时,Buffer 会记录下写了多少数据。一旦要读取数据,需要通过
flip() 方法将 Buffer 从写模式切换到读模式。在读模式下,可以读取之前写入到 Buffer
的所有数据。
一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空
缓冲区:调用 clear() 或 compact() 方法。clear() 方法会清空整个缓冲区。compact()
方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数
据将放到缓冲区未读数据的后面。
Buffer 主要有如下几种:
2.3 关于 Channel
Channel 是一个对象,可以通过它读取和写入数据。可以把它看做IO 中的流。但是它
和流相比还有一些不同:
1. Channel 是双向的,既可以读又可以写,而流是单向的
2. Channel 可以进行异步的读写
3. 对Channel 的读写必须通过buffer 对象
正如上面提到的,所有数据都通过Buffer 对象处理,所以,您永远不会将字节直接写入
到Channel 中,相反,您是将数据写入到Buffer 中;同样,您也不会从Channel 中读
取字节,而是将数据从Channel 读入Buffer,再从Buffer 获取这个字节。
因为Channel 是双向的,所以 Channel 可以比流更好地反映出底层操作系统的真实情
况。特别是在Unix 模型中,底层操作系统通常都是双向的。
在Java NIO 中Channel 主要有如下几种类型:
File
文档评论(0)