转:Java NIO(3)
要想讲清楚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打开文件源码:
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class MemoryMappedFileExample
- {
- static int length = 0x8FFFFFF; // 128 Mb
- public static void main(String[] args) throws Exception
- {
- MappedByteBuffer out = new RandomAccessFile("howtodoinjava.dat", "rw")
- .getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);
- for (int i = 0; i < length; i++)
- {
- out.put((byte) 'x');
- }
- System.out.println("Finished writing");
- }
- }
使用Java nio读取文件内容源码:
- import java.io.File;
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class MemoryMappedFileReadExample
- {
- private static String bigExcelFile = "bigFile.xls";
- public static void main(String[] args) throws Exception
- {
- //Create file object
- File file = new File(bigExcelFile);
- //Get file channel in readonly mode
- FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel();
- //Get direct byte buffer access using channel.map() operation
- MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
- // the buffer now reads the file as if it were loaded in memory.
- System.out.println(buffer.isLoaded()); //prints false
- System.out.println(buffer.capacity()); //Get the size based on content size of file
- //You can read the file from this buffer the way you like.
- for (int i = 0; i < buffer.limit(); i++)
- {
- System.out.print((char) buffer.get()); //Print the content of file
- }
- }
- }
使用Java nio写入文件新的内容:
- import java.io.File;
- import java.io.RandomAccessFile;
- import java.nio.MappedByteBuffer;
- import java.nio.channels.FileChannel;
- public class MemoryMappedFileWriteExample {
- private static String bigExcelFile = "test.txt";
- public static void main(String[] args) throws Exception {
- // Create file object
- File file = new File(bigExcelFile);
- //Delete the file; we will create a new file
- file.delete();
- // Get file channel in readonly mode
- FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel();
- // Get direct byte buffer access using channel.map() operation
- MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 4096 * 8 * 8);
- //Write the content using put methods
- buffer.put("howtodoinjava.com".getBytes());
- }
- }
可见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)的更多相关文章
- 源码分析netty服务器创建过程vs java nio服务器创建
1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...
- 支撑Java NIO 与 NodeJS的底层技术
支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...
- JAVA NIO学习笔记1 - 架构简介
最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...
- Java NIO概述
Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然 Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Se ...
- JAVA NIO Socket通道
DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...
- JAVA NIO FileChannel 内存映射文件
文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...
- java nio系列文章
java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍 (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...
- Java NIO (转)
Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...
- Java NIO使用及原理分析(1-4)(转)
转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...
- Java - NIO
java.nio:NIO-2: NIO 面向流的IO体系一次只能处理一个或多个字节/字符,直至读取所有字节/符,且流中的数据不能前后移动.效率低,当数据源中没有数据时会阻塞线程.Java-4提供的新A ...
随机推荐
- thinkphp3.2 where 条件查询 复查的查询语句
复查的查询语句 有的时候,我们希望通过一次的查询就能解决问题,这个时候查询条件往往比较复杂,但是却比多次查询库来的高效. 实在是搞不定的话就直接用$where[‘_string’] = ‘xxxx’, ...
- Open source cryptocurrency exchange
Peatio: https://github.com/peatio/peatio ViaBTC: https://github.com/viabtc/viabtc_exchange_server
- 工作中遇到的比较奇怪的一些sql(一些子查询)
在列中进行子查询 1.在一个表中有多个员工ID,比如一个下单员工,一个修改订单的员工,可以使用在列中进行子查询,具体如下: ( SELECT staff_name FROM sp_staff_basi ...
- selenium+PhantomJS 抓取淘宝搜索商品
最近项目有些需求,抓取淘宝的搜索商品,抓取的品类还多.直接用selenium+PhantomJS 抓取淘宝搜索商品,快速完成. #-*- coding:utf-8 -*-__author__ =''i ...
- Flume使用(案例分析)
Flume官方文档 Usage: bin/flume-ng <command> [options]... commands: help display this help text age ...
- SyntaxError: Non-ASCII character '\xe4' in file test.py on line 3, but no encoding declared。
可以查看到pycharm右下角文件的编码方式, 如果编码方式不一致,则在设置中修改编码方式: http://jingyan.baidu.com/article/c843ea0ba55f0977931e ...
- 5,Linux之文档与目录结构
Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到某一个目录下,用户通过操作目录来 ...
- sql查询作业答案
sql查询作业答案 阅读目录 一 题目 二 答案 一 题目 1.查询所有的课程的名称以及对应的任课老师姓名 2.查询学生表中男女生各有多少人 3.查询物理成绩等于100的学生的姓名 4.查询平均成 ...
- CSS3 loading效果全
梦想天空 关注前端开发技术 ◆ 推动 HTML5 & CSS3 技术发展 ◆ 本博客全新站点:yyyweb.com 欢迎围观:) 首页 管理 订阅 网页设计 JavaScript jQuery ...
- PJSIP-PJLIB(samples) (the usage of the pjlib lib) (eg:string/I/O)
Here are some samples about PJLIB! PJLIB is the basic lib of PJSIP, so we need master the lib first ...