谈谈NIO和IO
Channel,Buffer 和 Selector 构成了核心的API。
其它组件,如Pipe和FileLock,只不过是与三个核心组件共同使用的工具类。
Channel和Buffer
基本上,所有的 IO 在NIO 中都从一个Channel 开始。
Channel和Buffer有好几种类型。下面是JAVA NIO中的一些主要Channel的实现:
- FileChannel:从文件中读写数据。
- DatagramChannel:能通过UDP读写网络中的数据。
- SocketChannel: 能通过TCP读写网络中的数据。
- ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
以下是Java NIO里关键的Buffer实现:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
Java NIO 还有个 MappedByteBuffer,用于表示内存映射文件
Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。
例如,在一个聊天服务器中。在一个单线程中使用一个Selector处理3个Channel
Java NIO的通道类似流,但又有些不同:
- 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
- 通道可以异步地读写。
- 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
Buffer的基本用法:
使用Buffer读写数据一般遵循以下四个步骤:
- 写入数据到Buffer
- 调用
flip()方法 - 从Buffer中读取数据
- 调用
clear()方法或者compact()方法
clear()方法会清空整个缓冲区。
compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。
Buffer的三个属性:
position和limit的含义取决于Buffer处在读模式还是写模式。
不管Buffer处在什么模式,capacity的含义总是一样的。
写数据到Buffer有两种方式:
- 从Channel写到Buffer。
- 通过Buffer的put()方法写到Buffer里。
从Buffer中读取数据有两种方式:
- 从Buffer读取数据到Channel。
- 使用get()方法从Buffer中读取数据。
分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer
中。
聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,因此,Channel 将多个Buffer中的数据“聚集(gather)”后发送到
Channel。
Java NIO中的DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。
Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
面向流与面向缓冲
IO是面向流的,NIO是面向缓冲区的。
Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。
此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。
Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。
但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
阻塞与非阻塞IO
Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任
何事情了。
Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻
塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。
非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通
道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
选择器
Java NIO的选择器允许一个单独的线程来监视多个输入通道,
你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。
这种选择机制,使得一个单独的线程很容易来管理多个通道。
谈谈NIO和IO的更多相关文章
- 面试官:谈谈你对IO流和NIO的理解
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
- Java中 NIO与IO的区别
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- java nio 与io区别
转自:http://blog.csdn.net/keda8997110/article/details/19549493 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使 ...
- Java NIO与IO的区别和比较
传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大.使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数 ...
- Java基础知识强化之IO流笔记83:NIO与IO
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- Java NIO和IO的主要区别
From :http://blog.csdn.net/keda8997110/article/details/19549493 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部 ...
- Java中的NIO和IO的对比分析
总的来说,java中的IO和NIO主要有三点区别: IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的 ...
- Java NIO 和 IO 的区别详解
Java NIO为jdk1.4提供了新的API,本文主要来比较一下Java中NIO和IO的区别,Java初学者可以了解一下. 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分 ...
- Java NIO与IO
当学习了Java NIO和IO的API后,一个问题立即涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们怎样影响您的代 ...
随机推荐
- POJ 2289 Jamie's Contact Groups
二分答案+网络最大流 #include<cstdio> #include<cstring> #include<cmath> #include<vector&g ...
- Chapter 1 First Sight——13
It was just drizzling still, not enough to soak me through immediately as I reached for the house ke ...
- Angularjs循环二维数组
<div ng-app> <div ng-controller="test"> <div ng-repeat="links in slide ...
- BAT54C 二极管是如何工作的?
这是一个多电源供电的电路:Vcc是正常供电电源(如5V,由市电变换得到),电压大于(Vcc1-Vf),正常供电时二极管不导通:Vcc1是电池供电电源,当Vcc撤掉时,DD1(上边的二极管)导通,由Vc ...
- POJ 3984 迷宫问题 记录路径的广搜
主要是学一下如何在广搜中记录路径:每找到一个点我就记录下这个点是由那个点得来的,这样我找到最后个点后,我就可以通过回溯得到我走过的路径,具体看代码吧~ #include<cstdio> # ...
- spider JAVA如何判断网页编码 (转载)
原文链接 http://www.cnblogs.com/nanxin/archive/2013/03/27/2984320.html 前言 最近做一个搜索项目,需要爬取很多网站获取需要的信息.在爬取网 ...
- apk反汇编之smali语法
类型 Dalvik的字节码中拥有两个主要的类型:基类和引用类型.引用类型 引用类型是对象和数组,其他的一切都是基类 基类被一个简单的字符描述.我没有提出这些缩写词———他们实际以字符串的形式存储于 ...
- JS面向对象基础
以往写代码仅仅是为了实现特定的功能,后期维护或别人重用的时候,困难很大. Javascript作为完全面向对象的语言,要写出最优的代码,需要理解对象是如何工作的. 1. 对象是javasc ...
- JSTL select和checkbox的用法
select的 用法 <select id="roleIds" name="roleIds" multiple="true" back ...
- Andriod学习笔记 - 参考
Andriod学习笔记 - 参考 自定义实现圆形播放进度条(android,飞一般的感觉) 盘点Android开发者必备的十大开发工具