一、序言
关于NIO 相关介绍也很多了,这里主要目的还是通过自己的学习,分享一部分自己的理解,计划从基本概念到原理、到使用、到一些源码底层的分析,也回顾和总结自己的学习历程,今天先介绍概念。
二、NIO介绍
NIO 从JDK1.4 提出的,介绍是为了弥补IO的不足,提供了更高效的方式,提出一个通道(channel)的概念。源于IO的不足,还在在于它始终以流的形式对数据的传输和接受,当然NIO也差不多,但是NIO 提供了一种内存映射数据的方式,
简单的理解是:IO 原来是用固定的水管传输和接受水源,NIO可以提供一种用桶的方式传输和接受水源。比如在取水过程中,IO可以让接水,NIO可以直接一次打满一桶水,从效率上看,很明显的,当然这仅仅是一个好处,其他的我们后面解释。
三、通道和缓冲区
缓冲区(buffer):这个很好理解,即使IO也有这个概念,就就像我们读、写文件的时候,不会拿到一个字节,就对文件进行读、写操作,一般情况会建立一个缓存区数组,比如new byte[1024*4],然后将缓冲区的数据一次操作。在NIO中这里的原理其实一样的,可能细节实现上有些区别。
通道(channle): 这玩意儿,它需要从缓冲区获取数据,缓冲区也可以从通道里面提取数据,相当于我另外开辟了一个空间来存放我的数据,而且是双向的,对里面数据的掌控性也更好,好吧, 这些都是空话,实践出真知,我们后面实践的时候再对它进行细致的描述。
四、JDK 和 代码示例
全理论化的东西,是很烦人,即使写得很大白话,还是代码看着亲切。
1.先看看buffer 缓冲区: 这个其实也是装老的byte[] ,先看看我们将文件流放到byte 数组的写法区别
// 这是原始方式之一 FileInputStream is = new FileInputStream(name); // 这个区间可以自己定义 byte[] buff = new byte[is.available()]; is.read(buff); return buff;
// 这是新方式 FileInputStream f = new FileInputStream(name); // 获得通道,这里用了API 没公布的一些类,组合而成,有时间可以去看 // 看源码 FileChannel channel = f.getChannel(); // 创建一个缓冲区 ByteBuffer buffer = ByteBuffer.allocate(f.available()); // 从通道读取放入缓冲区 channel.read(buffer); // 注意,这里如果是分配的直接缓冲区 ,此方法会出错的,可以看源码 byte[] bytes = buffer.array();
上面的例子,其实你也不知道有啥好处,仅仅熟悉一下必要的步骤:通道<---> 缓冲区
下面我们来看看文件复制的操作:
// 原始方式的文件复制 public static void copyFile(String orgFile,String targetFile) throws Exception{ FileInputStream in = new FileInputStream(orgFile); FileOutputStream out = new FileOutputStream(targetFile); byte[] buff = new byte[1024*8]; int len = 0; while((len = in.read(buff)) != -1){ out.write(buff,0,len); } }
// 这是利用通道 缓冲区 的方式,和上面差不多 public static void copyFile2(String orgFile,String targetFile) throws Exception{ FileInputStream in = new FileInputStream(orgFile); FileOutputStream out = new FileOutputStream(targetFile); FileChannel orgChannel = in.getChannel(); FileChannel tarChannel = out.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024*8); int len = 0; while((len = orgChannel.read(buffer)) != -1){ buffer.flip(); tarChannel.write(buffer); buffer.clear(); } }
// 这个是直接用API 的方式 public static void copyFile3(String orgFile,String targetFile) throws Exception{ FileInputStream in = new FileInputStream(orgFile); FileOutputStream out = new FileOutputStream(targetFile); FileChannel orgChannel = in.getChannel(); FileChannel tarChannel = out.getChannel(); orgChannel.transferTo(0, orgChannel.size(), tarChannel); }
上面测试我用了一个大于JVM 限制的文件复制,结果是最后一种最快啦~。~(小文件就算了)
关于通道复制速度的解释:http://www.ibm.com/developerworks/cn/java/j-zerocopy/ 很详细
2.关于通道这个东西我的理解是:就像给我们数据源和地点之间加了一个大的用于传输的通道,这不是简单的让字节流通过的通道,而是里面允许我们做更多的检测、加速、返回等等操作的通道,后面分析源码的时候再体会吧。
关于缓冲区要说到的几个元素和方法,比如我们刚才用到的flip和clear。首先要理解这个缓冲区其实就是一个byte[] 数组的空间,里面有这几个元素:
Capacity:这表示容量,也就是说我数组的最大长度
position: 相当于指针,当我们操作数组里面元素的时候,这个会跟着移动,记录我们的位置,方便我们记录下次要用数据。
mark:标记位置,和事务的回滚位置差不多,相当于我们在这个位置记录一下,下一次我可以返回到这个位置干事。
limit :我们只能读操作到位置,比如我10长度的数组,只有前面6个又数据,那么我就设置只能操作前面6个有效的。
关于基本的东西可以看看源码,很容易,也可以看看这文章:
http://www.ibm.com/developerworks/cn/education/java/j-nio/section5.html
小结:
1.这里仅仅介绍下NIO 的使用基本情况,没有深入,它的优势还在于它的不阻塞模式,和Selector管理模式,后面会根据原理和源码分析。
相关推荐
学习Netty,可以从基础的Socket编程开始,然后深入理解Java NIO的基本概念,接着熟悉Netty提供的各种组件和API,通过编写简单的服务端和客户端程序来实践。随着对Netty的理解加深,可以尝试实现更复杂的网络应用,如...
本示例"JAVA-NIO-DEMO"提供了关于Java NIO的实际应用,通过Anontion(注解)、Applet(小程序)和NIO的Demo,帮助开发者更深入地理解和掌握这些概念。 首先,让我们深入了解Java NIO。NIO的核心组件包括: 1. **...
本示例代码旨在帮助开发者理解如何使用Java NIO和Reactor模式构建网络服务。尽管测试代码可能不完全准确,但它能展示基本的原理和工作流程。 首先,我们要了解什么是Reactor模式。Reactor模式是一种事件驱动的设计...
- **学习目标**:理解Socket通道的基本概念和使用场景。 #### 8. Java NIO-Channel-ServerSocketChannel - **主要内容**:详细介绍ServerSocketChannel的创建和使用方法。 - **学习目标**:学会如何创建并监听...
Java中的IO与NIO是Java开发中至关重要的概念,它们主要负责数据的输入与输出操作。在面试中,了解和掌握这些知识点对于成为一名合格的Java开发者至关重要。 首先,Java的IO流体系是其核心特性之一。IO流可以分为四...
- **教程文档**:解释了NIO的基本概念、用法以及与其他I/O模型的对比。 - **测试用例**:用于验证NIO功能的正确性,可能包括压力测试和性能测试。 - **实战项目**:可能包含一个实际应用NIO的简单服务器或客户端程序...
首先,让我们从基础开始,了解这些I/O模型的基本概念: 1. **BIO(阻塞I/O)**:这是最传统的I/O模型,在Java早期版本中广泛使用。当一个线程进行读写操作时,如果数据没有准备好,该线程会被挂起,直到数据准备...
- **基本概念**:缓冲区是指在内存中预先分配的一段连续的空间,用于暂时存储输入/输出数据。 - **作用**:缓冲区作为 I/O 操作的数据中转站,提高了数据处理效率。 - **类型**:根据数据类型的不同,Java 提供了...
为了充分利用这个工具,你需要理解NIO的基本概念,熟悉Java编程,尤其是网络编程部分,同时能够阅读和理解配置文件,以及源代码的结构和逻辑。如果想深入了解,可以尝试运行提供的脚本并查看源码,或者访问提供的...
NIO基本概念 - **通道(Channel)**: 通道是NIO的核心概念,它类似于流,但可以双向传输数据。常见的通道类有FileChannel、SocketChannel和ServerSocketChannel等。 - **缓冲区(Buffer)**: 缓冲区是NIO中的另...
通过以上内容,我们可以对NIO的核心概念和基本操作有了全面的认识。在实际项目中,结合选择器的使用,可以构建高并发、高性能的I/O服务。在深入研究NIO的同时,理解并熟练运用这些工具,将使我们的编程工作更加...
本项目"nio-demo"是针对NIO编程的一个演示,通过一系列示例代码,帮助我们理解和实践NIO的基本用法。** 1. **文件读写与文件拷贝:** 在NIO中,`java.nio`包提供了`FileChannel`类,它允许我们高效地在文件之间...
在Java NIO流篇1的学习中,我们将深入探讨NIO的核心概念和使用方法。 首先,我们从【第1节】 Java NIO流-简介和概述开始。这一部分主要介绍了NIO的基本理念和相对于BIO的优势。NIO的核心特点是它支持非阻塞I/O,这...
- **Channel 基础**:介绍了 Channel 的基本概念和使用方法。 - **散列/收集 (Scatter/Gather)**:解释了如何使用 Channel 进行散列/收集操作,这是一种优化读写操作的技术。 - **FileChannel**:详细讨论了 ...
Java NIO(New IO)是Java 1.4版本引入的一个新模块,是对传统IO模型的补充和扩展...通过本教程的学习,开发者不仅可以掌握NIO的基本概念,还能了解其在实际开发中的应用,为编写高效、灵活的Java程序打下坚实的基础。
本篇将详细讲解如何使用NIO实现邮件接收,主要涉及JavaMail API和NIO的核心概念。 首先,JavaMail API是Java平台上的一个用于处理邮件的开放源码库,它提供了创建、发送、接收和管理邮件的一系列接口和类。而NIO则...
虽然这里只介绍了基本概念,但在实际应用中,可能还需要考虑线程安全、心跳检测、重连机制等复杂问题。NIO为高性能网络编程提供了强大的工具,理解并熟练运用这些概念对于开发高效、稳定的网络应用至关重要。