`

【Java NIO 简例】NIO vs IO

    博客分类:
  • Java
nio 
阅读更多

原文:《Java NIO vs. IO

当学习Java NIO 和 IO 的API时,很快会遇到一个问题:
什么时候用IO,什么时候用NIO?

我会尝试在本文提供一些关于Java NIO 与 IO 的不同点、使用案例、及它们将如何影响代码设计方面的见解。

 

NIO 与 IO 的主要不同

下表总结了Java NIO 和 IO 的主要不同。我会在后文详细论述每一个不同点。

IO NIO
面向 Stream 面向 Buffer 
阻塞式IO 非阻塞IO
  Selector

 

面向Stream vs 面向Buffer

NIO 和 IO的第一个最大不同是:IO面向Stream,NIO面向Buffer。这意味着什么?

 

IO 面向 Stream 意味着你可以从stream一次读取一个或多个字节。读多少个字节取决于你。它们不会被缓存在任何地方。进一步而言,你无法在stream数据流中往前或往后移动。如果你需要在这些数据中往前或往后移动,你需要先将其缓存在一个buffer中。

 

NIO 面向 Buffer 稍微有点不同。数据被读到一个buffer中,然后再被处理。你可以根据需要在这个buffer中往前或往后移动。这给了你更多处理过程中的扩展性。但是你也需要检查buffer是否包含了进行完整处理所需的所有数据。而且你需要确保往buffer读入更多数据时不会覆盖掉那些尚未被处理的数据。

 

阻塞 vs 非阻塞

Java IO 的各种Stream是阻塞式的。这意味着,当线程调用了 read() 或 write() 方法,该线程会被阻塞,直到有数据可读,或所有数据被写入。在此期间,该线程无法做其它任何事情。

 

Java NIO 的非阻塞模式允许线程从channel请求数据,且只会得到当前就绪的数据;如果当前没有就绪的数据,就得不到任何数据。且该线程不会被阻塞直到有数据就绪可读,而是会理解返回并可以做其它事情。

非阻塞写数据也类似。线程可以请求向channel写入数据,但不会被阻塞直到所有数据被写入。线程可以继续做其它事情。

线程处于空闲未被阻塞于IO调用时,通常可以处理其它channel的IO。也就是说现在单线程可以处理多channel的输入和输出。

 

Selector

Selector 允许单线程监视多个 Channel。你可以将多个 Channel 注册到一个 Selector 上,让后用单个线程“选出”就绪可读或可写的 Channel。此 Selector 机制使得单线程管理多Channel更容易。

 

NIO 和 IO 如何影响应用设计

选择 NIO 或 IO 会在以下几个方面影响你的应用设计:

  1. 调用的API(来自NIO的类还是IO的类)
  2. 处理数据的过程
  3. 处理数据的线程数

调用的API

毫不意外,使用NIO与IO所调用的API是不同的。在NIO中,数据必须先被读到一个Buffer中,然后再处理;在IO中,数据是被直接从Stream读出来进行处理的。

 

处理数据的过程

IO模式

代码示例:

// InputStream input = ...
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line1 = reader.readLine();
String line2 = reader.readLine();


 

NIO模式

代码示例:

ByteBuffer buffer = ByteBuffer.allocate(1024);
int readByteCount = channel.read(buffer);

while (!isDataComplete(readByteCount)) {
  readByteCount = channel.read(buffer);
}

channel.read(buffer) 所读取到的数据量是不一定的,可能这些数据并不足以用于后续业务的执行,而需要多次执行读取操作以获得义务意义上完整的数据。
这就引入了低效的数据完整性检查操作,及凌乱复杂的程序设计:

  • isDataComplete(int) 方法用于检查数据是否足以用于后续业务执行;
  • while 循环直到获得足够的数据量。


 

总结

NIO 允许你用单个(或更多)线程管理多个 Channel (如,网络连接 或 文件)。但是其代价是更复杂的数据解析操作(相比与从阻塞Stream中读取数据)。

 

# 如果你需要同时管理上千个连接,且这些连接都只发送少量的数据(如,聊天系统的服务端),那么用NIO实现服务端可能会有优势。
同样的,如果你需要保持大量与其它机器的连接(如,P2P网络),那么用单个线程管理所有向外的连接可能有优势。
这个 单线程-多连接 的设计简化如下:


 

 

# 如果连接较少,且都占用较高的带宽,单次传输的数据量非常多,也许一个典型的IO服务端实现最合适。设计简化如下:

  • 大小: 24.8 KB
  • 大小: 17.9 KB
  • 大小: 16 KB
  • 大小: 23.2 KB
分享到:
评论

相关推荐

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道...Java NIO系列教程(十二) Java NIO与IO

    java io 与java nio区别

    ### Java IO 与 Java NIO 的区别 在深入探讨Java IO与Java NIO之间的区别之前,我们先简单回顾一下这两种I/O模型的基本概念。 #### 1. Java IO(Blocking IO) Java IO,也称为传统的阻塞式IO或同步阻塞式IO,是...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    Ioserver java Nio socket 框架

    Ioserver java Nio socket 框架 是个不错的NIO 通讯框架,本来想学习mina框架,看了看mina的源码太头痛,本人觉得看懂了Ioserver 再看mina的框架,想多的学习 java NIO 的也可以下载 看看,很值得学习啊!!!

    Java NIO与IO性能对比分析.pdf

    Java NIO(New IO,也称为Non-blocking IO)和传统的Java IO是Java编程语言中用于处理I/O操作的两种主要技术。随着互联网用户数量的激增,企业对应用程序的并发处理能力提出了更高的要求。为了解决传统Java IO模型在...

    java NIO.zip

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...

    java nio与io性能测试

    Java NIO(New IO)是Java 1.4引入的一个新模块,它是对传统IO(Input/Output)的扩展,提供了更高效的数据传输方式。在Java IO中,数据的读写是通过流进行的,而NIO则引入了通道(Channel)和缓冲区(Buffer)的...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    Java IO NIO and NIO 2 无水印pdf

    Java IO NIO and NIO 2 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn...

    Java IO_NIO

    然而,传统的IO模型在处理大量并发连接时表现出效率较低的问题,为了解决这个问题,Java引入了NIO(Non-blocking Input/Output)模型。 **Java IO核心概念** Java IO的核心类包括InputStream、OutputStream、Reader...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    nio.zip_NIO_NewIO_NIO.c_java NIO chm_java nio

    NIO(New IO)是Java平台中用于处理输入/输出操作的一种高级API,它在Java 1.4版本中引入,以替代传统的IO流模型。NIO提供了更高效、更灵活的数据传输方式,尤其适用于高并发和大数据量的场景。 在Java的NIO体系中...

    java nio 包读取超大数据文件

    Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本中得到了进一步增强和完善。相较于传统的Java IO,NIO具有更高的性能和...

    Java IO, NIO and NIO.2

    Java IO、NIO以及NIO.2是Java中用于处理输入/输出操作的三种主要机制。本书《Java IO, NIO and NIO.2》旨在深入浅出地介绍这些机制,同时书中内容均为英文。接下来将详细介绍这些知识点。 **Java IO** Java IO是...

    Java IO与NIO文档

    Java IO与NIO是Java平台中用于处理输入输出操作的核心技术。它们在处理数据传输、文件操作、网络通信等方面起着至关重要的作用。本篇将深入探讨这两个领域,旨在帮助开发者更好地理解和应用这些概念。 首先,Java ...

    Java IO NIO and NIO 2 epub

    Java IO NIO and NIO 2 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

Global site tag (gtag.js) - Google Analytics