`
greemranqq
  • 浏览: 975519 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

nio ---基本概念和使用

阅读更多

一、序言 

       关于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管理模式,后面会根据原理和源码分析。

    

  

分享到:
评论

相关推荐

    Java-NIO-Netty框架学习

    学习Netty,可以从基础的Socket编程开始,然后深入理解Java NIO的基本概念,接着熟悉Netty提供的各种组件和API,通过编写简单的服务端和客户端程序来实践。随着对Netty的理解加深,可以尝试实现更复杂的网络应用,如...

    JAVA-NIO-DEMO

    本示例"JAVA-NIO-DEMO"提供了关于Java NIO的实际应用,通过Anontion(注解)、Applet(小程序)和NIO的Demo,帮助开发者更深入地理解和掌握这些概念。 首先,让我们深入了解Java NIO。NIO的核心组件包括: 1. **...

    socket-nio-single-reactor.zip

    本示例代码旨在帮助开发者理解如何使用Java NIO和Reactor模式构建网络服务。尽管测试代码可能不完全准确,但它能展示基本的原理和工作流程。 首先,我们要了解什么是Reactor模式。Reactor模式是一种事件驱动的设计...

    java网络编程NIO视频教程

    - **学习目标**:理解Socket通道的基本概念和使用场景。 #### 8. Java NIO-Channel-ServerSocketChannel - **主要内容**:详细介绍ServerSocketChannel的创建和使用方法。 - **学习目标**:学会如何创建并监听...

    Java中的IO与NIO-jiava求职面试-15题,答案

    Java中的IO与NIO是Java开发中至关重要的概念,它们主要负责数据的输入与输出操作。在面试中,了解和掌握这些知识点对于成为一名合格的Java开发者至关重要。 首先,Java的IO流体系是其核心特性之一。IO流可以分为四...

    nio-study:尼奥研究

    - **教程文档**:解释了NIO的基本概念、用法以及与其他I/O模型的对比。 - **测试用例**:用于验证NIO功能的正确性,可能包括压力测试和性能测试。 - **实战项目**:可能包含一个实际应用NIO的简单服务器或客户端程序...

    BIO、NIO、AIO、Netty 、TCP全网最全解析!Netty中提供了哪些线程模型?

    首先,让我们从基础开始,了解这些I/O模型的基本概念: 1. **BIO(阻塞I/O)**:这是最传统的I/O模型,在Java早期版本中广泛使用。当一个线程进行读写操作时,如果数据没有准备好,该线程会被挂起,直到数据准备...

    Java NIO核心概念总结篇

    - **基本概念**:缓冲区是指在内存中预先分配的一段连续的空间,用于暂时存储输入/输出数据。 - **作用**:缓冲区作为 I/O 操作的数据中转站,提高了数据处理效率。 - **类型**:根据数据类型的不同,Java 提供了...

    talent-nio3.0.0备份

    为了充分利用这个工具,你需要理解NIO的基本概念,熟悉Java编程,尤其是网络编程部分,同时能够阅读和理解配置文件,以及源代码的结构和逻辑。如果想深入了解,可以尝试运行提供的脚本并查看源码,或者访问提供的...

    JAVA-NIO程序设计完整实例

    NIO基本概念 - **通道(Channel)**: 通道是NIO的核心概念,它类似于流,但可以双向传输数据。常见的通道类有FileChannel、SocketChannel和ServerSocketChannel等。 - **缓冲区(Buffer)**: 缓冲区是NIO中的另...

    NIO学习系列:核心概念及基本读写

    通过以上内容,我们可以对NIO的核心概念和基本操作有了全面的认识。在实际项目中,结合选择器的使用,可以构建高并发、高性能的I/O服务。在深入研究NIO的同时,理解并熟练运用这些工具,将使我们的编程工作更加...

    nio-demo:NIO编辑演示

    本项目"nio-demo"是针对NIO编程的一个演示,通过一系列示例代码,帮助我们理解和实践NIO的基本用法。** 1. **文件读写与文件拷贝:** 在NIO中,`java.nio`包提供了`FileChannel`类,它允许我们高效地在文件之间...

    Java语言基础教程-Java NIO流篇1

    在Java NIO流篇1的学习中,我们将深入探讨NIO的核心概念和使用方法。 首先,我们从【第1节】 Java NIO流-简介和概述开始。这一部分主要介绍了NIO的基本理念和相对于BIO的优势。NIO的核心特点是它支持非阻塞I/O,这...

    Java.NIO资源下载资源下载

    - **Channel 基础**:介绍了 Channel 的基本概念和使用方法。 - **散列/收集 (Scatter/Gather)**:解释了如何使用 Channel 进行散列/收集操作,这是一种优化读写操作的技术。 - **FileChannel**:详细讨论了 ...

    Java语言基础教程-Java NIO流篇2

    Java NIO(New IO)是Java 1.4版本引入的一个新模块,是对传统IO模型的补充和扩展...通过本教程的学习,开发者不仅可以掌握NIO的基本概念,还能了解其在实际开发中的应用,为编写高效、灵活的Java程序打下坚实的基础。

    NIO实现邮件接收原码

    本篇将详细讲解如何使用NIO实现邮件接收,主要涉及JavaMail API和NIO的核心概念。 首先,JavaMail API是Java平台上的一个用于处理邮件的开放源码库,它提供了创建、发送、接收和管理邮件的一系列接口和类。而NIO则...

    使用NIO方式完成简单的通信

    虽然这里只介绍了基本概念,但在实际应用中,可能还需要考虑线程安全、心跳检测、重连机制等复杂问题。NIO为高性能网络编程提供了强大的工具,理解并熟练运用这些概念对于开发高效、稳定的网络应用至关重要。

Global site tag (gtag.js) - Google Analytics