要想讲清楚nio的原理和它的优点得先清楚Java应用程序的文件读写原理和虚拟内存的原理。Java文件读取原理可参见如下图:

当应用程序需要读取文件的时候,内核首先通过DMA技术将文件内容从磁盘读入内核中的buffer,然后Java应用进程再从内核的buffer将数据读取到应用程序的buffer。

为了提升I/O效率和处理能力,操作系统采用虚拟内存的机制。虚拟内存也就是我们常说的交换内存,它实际上是硬盘上的文件,虚拟内存有两个作用:

1. 不同的虚拟内存可以映射到相同的物理内存,根据这个原理,可以简化文件读取流程,提升读取效率,效果如下图所示:

通过使用虚拟内存技术,将应用程序的buffer和内核的buffer都作为虚拟内存,并且两块不同的虚拟内存指向相同的物理内存,内核通过DMA将数据读取到buffer的时候,应用程序就可以直接使用这些数据了。

2. 通过使用虚拟内存,
应用程序可以使用比物理内存所能容纳得大得多的内存,并且也能够提高I/O效率。当物理内存中的数据不使用的时候,可以将物理内存中的数据放到虚拟内存
中,操作系统就可以腾出物理内存空间存储新的要处理的数据。当需要使用虚拟内存中的数据时,再可以把虚拟内存中的数据加载到物理内存中。因此物理内存可以
看做时虚拟内存中存放数据的cache。而上面所述的cache虚拟内存数据的过程,对应用程序来说时透明的,它可以像处理物理内存数据一样处理虚拟内存
中的数据。

Java nio通过使用虚拟内存技术将文件系统中的文件页和应用程序空间直接对应起来,使用nio后,文件的读写操作都是在虚拟内存中实现。这样在操作文件的时候,好像文件已经在内存中一样。采用了虚拟内存技术,使用Java nio方式可以很快的读取很大的文件。

Java nio打开文件可指定映射内容在所要映射的文件所在位置。使用Java nio打开文件源码:

  1. import java.io.RandomAccessFile;
  2. import java.nio.MappedByteBuffer;
  3. import java.nio.channels.FileChannel;
  4. public class MemoryMappedFileExample
  5. {
  6. static int length = 0x8FFFFFF; // 128 Mb
  7. public static void main(String[] args) throws Exception
  8. {
  9. MappedByteBuffer out = new RandomAccessFile("howtodoinjava.dat", "rw")
  10. .getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);
  11. for (int i = 0; i < length; i++)
  12. {
  13. out.put((byte) 'x');
  14. }
  15. System.out.println("Finished writing");
  16. }
  17. }

使用Java nio读取文件内容源码:

  1. import java.io.File;
  2. import java.io.RandomAccessFile;
  3. import java.nio.MappedByteBuffer;
  4. import java.nio.channels.FileChannel;
  5. public class MemoryMappedFileReadExample
  6. {
  7. private static String bigExcelFile = "bigFile.xls";
  8. public static void main(String[] args) throws Exception
  9. {
  10. //Create file object
  11. File file = new File(bigExcelFile);
  12. //Get file channel in readonly mode
  13. FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel();
  14. //Get direct byte buffer access using channel.map() operation
  15. MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
  16. // the buffer now reads the file as if it were loaded in memory.
  17. System.out.println(buffer.isLoaded());  //prints false
  18. System.out.println(buffer.capacity());  //Get the size based on content size of file
  19. //You can read the file from this buffer the way you like.
  20. for (int i = 0; i < buffer.limit(); i++)
  21. {
  22. System.out.print((char) buffer.get()); //Print the content of file
  23. }
  24. }
  25. }

使用Java nio写入文件新的内容:

  1. import java.io.File;
  2. import java.io.RandomAccessFile;
  3. import java.nio.MappedByteBuffer;
  4. import java.nio.channels.FileChannel;
  5. public class MemoryMappedFileWriteExample {
  6. private static String bigExcelFile = "test.txt";
  7. public static void main(String[] args) throws Exception {
  8. // Create file object
  9. File file = new File(bigExcelFile);
  10. //Delete the file; we will create a new file
  11. file.delete();
  12. // Get file channel in readonly mode
  13. FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel();
  14. // Get direct byte buffer access using channel.map() operation
  15. MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 4096 * 8 * 8);
  16. //Write the content using put methods
  17. buffer.put("howtodoinjava.com".getBytes());
  18. }
  19. }

可见Java nio的优势为:

1. 不需要使用read()或者write()操作就可以处理文件内容了

2. 修改文件后,修改自动flush到文件

3. nio方式能很快处理大文件和处理效率很快

参考文章:

http://howtodoinjava.com/2014/12/10/how-java-io-works-internally-at-lower-level/

http://howtodoinjava.com/2015/01/16/java-nio-2-0-memory-mapped-files-mappedbytebuffer-tutorial/

转:Java NIO(3)的更多相关文章

  1. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  2. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

  3. JAVA NIO学习笔记1 - 架构简介

    最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...

  4. Java NIO概述

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然 Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Se ...

  5. JAVA NIO Socket通道

      DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...

  6. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...

  7. java nio系列文章

    java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍   (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...

  8. Java NIO (转)

    Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...

  9. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  10. Java - NIO

    java.nio:NIO-2: NIO 面向流的IO体系一次只能处理一个或多个字节/字符,直至读取所有字节/符,且流中的数据不能前后移动.效率低,当数据源中没有数据时会阻塞线程.Java-4提供的新A ...

随机推荐

  1. 微信公众号支付java版本

    回调函数 @RequestMapping("/toPay") public String toPay(HttpServletRequest request, HttpServlet ...

  2. PHP 多参数方法的重构

    假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子: <?php function saveArticle($title, $content, $categoryId ...

  3. E - Nature Reserve CodeForces - 1059D

    传送门 There is a forest that we model as a plane and live nn rare animals. Animal number iihas its lai ...

  4. 17-比赛1 D - IPC Trainers (贪心 + 优先队列)

    题目描述 本次印度编程训练营(Indian Programming Camp,IPC)共请到了 N 名教练.训练营的日程安排有 M 天,每天最多上一节课.第 i 名教练在第 Di 天到达,直到训练营结 ...

  5. PHP.TP框架下商品项目的优化3-php封装下拉框函数

    php封装下拉框函数 因为在项目中会经常使用到下拉框,所以根据一个表中的数据制作下拉框函数,以便调用 //使用一个表的数据做下拉框函数 function buildSelect($tableName, ...

  6. spring里面的context:component-scan

    原文:http://jinnianshilongnian.iteye.com/blog/1762632 component-scan的作用的自动扫描,把扫描到加了注解Java文件都注册成bean &l ...

  7. 亲手搭建一个基于Asp.Net WebApi的项目基础框架2

    本篇目的:封装一些抽象类 1::封装日志相关类 2:封装一个Service操作类 3:封装缓存操作类 4:封装其他一些常用Helper 1.1在Framework项目里面建立好相关操作类文件夹,以便于 ...

  8. laravel5.5队列

    目录 简单实例 1. 简介和配置 1.1 好处 1.2 配置文件 1.3 队列驱动的必要配置 2. 创建任务 2.1 生成任务类 2.2 修改任务类 2.3 分发任务 2.4 自定义队列 & ...

  9. 关于 Inno Setup 报木马的问题处理

    用 Inno Setup 生成的安装包总是报木马,尝试了N次之后发现,把 Compression=lzma 改为 Compression=zip 就不会再报了,可能lzma的压缩算法导致delphi的 ...

  10. USACO刷题之路,开始了

    几天前,重新开始刷题了. 重新刷题有几个原因: 1.曾经的OI经历,如今除了悟性高些.知识多些,大多已经遗忘.不希望真的让之前的OI水平就这么丢了. 2.越来越觉得,刷题真的是一件很开心的事情.大学中 ...