Java中NIO和IO的比较

NIO是为了弥补IO操作的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道。管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征。

概念解释:


Channel——管道实际上就像传统IO中的流,到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象。一个 Buffer 实质上是一个容器对象。

每一种基本 Java 类型都有一种缓冲区类型:

ByteBuffer——byte
CharBuffer——char
ShortBuffer——short
IntBuffer——int
LongBuffer——long
FloatBuffer——float
DoubleBuffer——double

Selector——选择器用于监听多个管道的事件,使用传统的阻塞IO时我们可以方便的知道什么时候可以进行读写,而使用非阻塞通道,我们需要一些方法来知道什么时候通道准备好了,选择器正是为这个需要而诞生的。

NIO和传统的IO有什么区别呢?


1,IO是面向流的,NIO是面向块(缓冲区)的。

IO面向流的操作一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。,导致了数据的读取和写入效率不佳;

NIO面向块的操作在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多,同时数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。通俗来说,NIO采取了“预读”的方式,当你读取某一部分数据时,他就会猜测你下一步可能会读取的数据而预先缓冲下来。

2,IO是阻塞的,NIO是非阻塞的。

对于传统的IO,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。

而对于NIO,使用一个线程发送读取数据请求,没有得到响应之前,线程是空闲的,此时线程可以去执行别的任务,而不是像IO中那样只能等待响应完成。

NIO和IO适用场景

NIO是为弥补传统IO的不足而诞生的,但是尺有所短寸有所长,NIO也有缺点,因为NIO是面向缓冲区的操作,每一次的数据处理都是对缓冲区进行的,那么就会有一个问题,在数据处理之前必须要判断缓冲区的数据是否完整或者已经读取完毕,如果没有,假设数据只读取了一部分,那么对不完整的数据处理没有任何意义。所以每次数据处理之前都要检测缓冲区数据。

那么NIO和IO各适用的场景是什么呢?

如果需要管理同时打开的成千上万个连接,这些连接每次只是发送少量的数据,例如聊天服务器,这时候用NIO处理数据可能是个很好的选择。

而如果只有少量的连接,而这些连接每次要发送大量的数据,这时候传统的IO更合适。使用哪种处理数据,需要在数据的响应等待时间和检查缓冲区数据的时间上作比较来权衡选择。

通俗解释

最后,对于NIO和传统IO,有一个网友讲的生动的例子:

以前的流总是堵塞的,一个线程只要对它进行操作,其它操作就会被堵塞,也就相当于水管没有阀门,你伸手接水的时候,不管水到了没有,你就都只能耗在接水(流)上。

nio的Channel的加入,相当于增加了水龙头(有阀门),虽然一个时刻也只能接一个水管的水,但依赖轮换策略,在水量不大的时候,各个水管里流出来的水,都可以得到妥

善接纳,这个关键之处就是增加了一个接水工,也就是Selector,他负责协调,也就是看哪根水管有水了的话,在当前水管的水接到一定程度的时候,就切换一下:临时关上当

前水龙头,试着打开另一个水龙头(看看有没有水)。

当其他人需要用水的时候,不是直接去接水,而是事前提了一个水桶给接水工,这个水桶就是Buffer。也就是,其他人虽然也可能要等,但不会在现场等,而是回家等,可以做

其它事去,水接满了,接水工会通知他们。

这其实也是非常接近当前社会分工细化的现实,也是统分利用现有资源达到并发效果的一种很经济的手段,而不是动不动就来个并行处理,虽然那样是最简单的,但也是最浪费

资源的方式。

时间: 2024-10-31 03:36:37

Java中NIO和IO的比较的相关文章

java中nio的socket通信实例程序

虽然Java平台有不少相当不错的一步socket的框架,比如Netty,naga等,但是我们应该知其然并知其所以然. nio是java New IO 的简称,从jdk1.4里提供的新api,Sun官方标榜的特性如下: 为所有的原始类型提供 (Buffer) 缓存支持 字符集编码解码解决方案 Channel:一个新的原始 I/O 抽象 支持锁和内存映射文件的文件访问接口 提供多路 (non-bloking) 非阻塞式的高伸缩性网络 I/O 基本原理 NIO 有一个主要的类Selector,这个类似

java的nio之:浅析I/O模型

也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在 进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起,然后接着阐述了阻塞和非阻塞的区别,接着介绍了阻塞IO和非阻塞IO的区别,然后介绍了同步IO和异步IO的区别,接下来介绍了5种IO模型,最后 介绍了两种和高性能IO设计相关的设计模式(Reactor和Proactor). 以下是本文的目录大纲: 一.什么是同步?什么是异步? 二.什么是阻塞?什么是非

Java中对文件的操作

Java中对文件的操作 java中提供了io类库,可以轻松的用java实现对文件的各种操作.下面就来说一下如何用java来实现这些操作. 1.新建目录 <%@ page contentType="text/html;charset=gb2312"%> <% String filePath="c:/aaa/"; filePath=filePath.toString();//中文转换 java.io.File myFilePath=new java.i

Java NIO系列教程(十二) Java NIO与IO

原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html 作者:Jakob Jenkov   译者:郭蕾    校对:方腾飞 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代码设计. Java NIO和IO的主要区别 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分

Java NIO和IO的区别_java

下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异. 复制代码 代码如下: IO                NIO面向流            面向缓冲阻塞IO            非阻塞IO无                选择器 面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方.此外,它不能前后移动流中的数

java的nio之:java的nio系列教程之java的io和nio的区别

当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代码设计. Java NIO和IO的主要区别 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异. IO                NIO 面向流            面向缓冲 阻塞IO           非阻塞IO 无 选择器   面向流与面向缓冲 Java N

Java中IO流缓冲区的装饰模式的体现

一.Java中IO流缓冲区 import java.io.*; public class BufferedTest {public static void copy1(){InputStream is = null;OutputStream os = null;try{is = new FileInputStream("c:\\xy1.jpg");os = new FileOutputStream("d:\\xy2.jpg");int len = 0;byte[]

io流-java中的IO流使用情况

问题描述 java中的IO流使用情况 java中有很多读取和写入文件的操作 像FileWirter Writer Reader BufferWriter 等 我一直区分不清这几个的特点,有没有大神帮忙处理下,通常什么情况使用什么比较好.各有那些优点和缺点 解决方案 你可以上网搜索哦下,很多的 解决方案二: 有的有缓冲区,有的没有,有的没有:有的可以操纵字符文件,有的可以操纵字节文件,你可以按照这个进行分类 解决方案三: 这是我自己整理的,你可以参考下http://blog.csdn.net/ev

Java中IO流,输入输出流概述与总结

总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都是抽象类InputStream(字节输入流),或者抽象类Reader(字符输入流)的子类: 而所有输出流都是抽象类OutputStream(字节输出流)或者Writer(字符输出流)的子类. [首先需要明白的是:流是干什么的???(为了永久性的保存数据)   根据数据流向的不同分为输入流和输出流:   根据处理数据类型的不同分为字符流和字