(转载)Java NIO:NIO概述(一)
Java NIO:NIO概述
在上一篇博文中讲述了几种IO模型,现在我们开始进入Java NIO编程主题。NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题。本文下面分别从Java NIO的几个基础概念介绍起。
以下是本文的目录大纲:
一.NIO中的几个基础概念
二.Channel
三.Buffer
四.Selector
为了对原作者以示尊重,标明原文链接:
http://www.cnblogs.com/dolphin0520/p/3919162.html
一.NIO中的几个基础概念
在NIO中有几个比较关键的概念:Channel(通道),Buffer(缓冲区),Selector(选择器)。
首先从Channel说起吧,通道,顾名思义,就是通向什么的道路,为某个提供了渠道。在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:
|
1
2
3
4
5
6
7
8
9
|
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有注册的事件发生,便获取事件然后进行处理。
比如看下面的这个例子:

用单线程处理一个Selector,然后通过Selector.select()方法来获取到达事件,在获取了到达事件之后,就可以逐个地对这些事件进行响应处理。
二.Channel
在前面已经提到,Channel和传统IO中的Stream很相似。虽然很相似,但是有很大的区别,主要区别为:通道是双向的,通过一个Channel既可以进行读,也可以进行写;而Stream只能进行单向操作,通过一个Stream只能进行读或者写;
以下是常用的几种通道:
- FileChannel
- SocketChanel
- ServerSocketChannel
- DatagramChannel
通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。
下面给出通过FileChannel来向文件中写入数据的一个例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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。具体看下面这张图就理解了:

上面的图描述了从一个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送数据时,必须先将数据存入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个类构成了服务端处理业务的关键逻辑。
(转载)Java NIO:NIO概述(一)的更多相关文章
- java的nio之:java的nio系列教程之概述
一:java的nio的核心组件?Java NIO 由以下几个核心部分组成: ==>Channels ==>Buffers ==>Selectors 虽然Java NIO 中除此之外还 ...
- java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述
猛击这里 java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述
- 输入和输出--java的NIO
Java的NIO 实际开发中NIO使用到的并不多,我并不是说NIO使用情景不多,是说我自己接触的并不是很多,前面我在博客园和CSDN上转载了2篇别人写的文章,这里来大致总结下Java的NIO,大概了解 ...
- 理解Java的NIO
同步与阻塞 同步和异步是针对应用程序和内核的交互而言的. 同步:执行一个操作之后,进程触发IO操作并等待(阻塞)或者轮询的去查看IO的操作(非阻塞)是否完成,等待结果,然后才继续执行后续的操作. 异步 ...
- 一个小时就能理解Java的NIO必须掌握这三大要素!
同步与阻塞 同步和异步是针对应用程序和内核的交互而言的. 同步:执行一个操作之后,进程触发IO操作并等待(阻塞)或者轮询的去查看IO的操作(非阻塞)是否完成,等待结果,然后才继续执行后续的操作. 异步 ...
- Java:NIO 学习笔记-3
Java:NIO 学习笔记-3 根据 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 3. JAVA NIO 深入剖析 在讲解利用 NIO 实现通信架构之前,我们需要先来了解一下 NI ...
- Java:NIO 学习笔记-2
Java:NIO 学习笔记-2 上一篇 NIO 学习笔记-1 看了 尚硅谷 的相应教程,此处又对比看了 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 前言 在 Java 的软件设计开 ...
- JAVA bio nio aio
[转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...
- java的nio之:java的nio系列教程之buffer的概念
一:java的nio的buffer==>Java NIO中的Buffer用于和NIO通道Channel进行交互.==>数据是从通道channel读入缓冲区buffer,从缓冲区buffer ...
- java的nio之:java的nio系列教程之channel的概念
一:java的nio的channel Java NIO的通道类似流,但又有些不同: ==>既可以从通道中读取数据,又可以写数据到通道.但流的读写通常是单向的. ==>通道可以异步地读写. ...
随机推荐
- jquery.loadmask.js
Quick Start 下载之后的目录结构如下图所示: 使用此插件非常简单,如下步骤所示: 1. 引用jquery,1.2.3以上版本 <script type="text/java ...
- HL7及PIX相关的测试工具
最近在开发PIX项目时需要一些工具, 比如PIX各个Actor的测试工具, HL7消息的验证工具等等. 下面列下我找见的几个 必备工具. 1. http://hit-testing.nist.gov: ...
- Educational Codeforces Round 13 D. Iterated Linear Function (矩阵快速幂)
题目链接:http://codeforces.com/problemset/problem/678/D 简单的矩阵快速幂模版题 矩阵是这样的: #include <bits/stdc++.h&g ...
- Objc基础学习记录1
1.'-'系在实例方法前头 2.'+'类方法class method 相反; 3.void表示没有返回值; 4.&x 和c语言一样,代表的是x的在内存上的地址; 5.*y指向内存存储空间内的数 ...
- 再次理解JavaScript原型链和匿名函数
<!--------------------------------------------- 1.演示匿名加载 2.js单进程执行流 3.原型链理解 a.__proto__:属性每个对象都有 ...
- squid添加用户名密码认证
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...
- iOS Foundation 框架概述文档:常量、数据类型、框架、函数、公布声明
iOS Foundation 框架概述文档:常量.数据类型.框架.函数.公布声明 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业 ...
- Python 动态语言
1.在C++中,Animal a = Person(); 这样写是不行的,因为a的内容不能使用Person的内容来填充. 2.在Python中,变量不需要声明,而且可以赋任何值.Python是如何做到 ...
- C# 使用xsd文件验证XML 格式是否正确
C# 使用xsd文件验证XML 格式是否正确 核心示例代码: //创建xmlDocument XmlDocument doc = new XmlDocument(); //创建声明段 如<?xm ...
- vector<int> v2 = 42; 为何非法
C++ Primer 第四版,第十三章“复制控制” 习题13.2,为何vector<int> v2 = 42; 不能编译? 百度贴吧里的一位楼主给出了答案,本人认为正确,特此引用: 参考链 ...