java利用“映射文件访问”(MapperByteBuffer)处理文件与单纯利用Buffer来处理文件的快慢比较
处理文件是java经常使用的操作,在对一个“大文件”(比如超过64M)进行操作时一点点速度的提高都会带来性能的巨大提升。然而我们经常使用的BufferxxStream,来直接处理大文件时,往往力不从心。
java中“映射文件访问”机制则解决了这一问题,它把大文件的较小部分先放在内存里,将其余待读取的数据仍然放在硬盘里面。但是我们完全可以通过这样一个机制把这个大文件当作非常大的数组来使用。是不是很像操作系统里面对于应用的使用方法?没错,其实java正是利用了底层操作系统的文件映射工具来最大化提高性能。
一般为了即能读又能写,我们使用RandomAccessFile来进行测试,同过该文件上的通道,然后调用FileChannel中的map()所产生的MappedByteBuffer,在map方法中有三个参数map(FileChannel.MapMode mode, long position, long size)。
其中mode 来决定映射的文件访问的读/写机制,可以设置MapMode.READ_ONLY, MapMode.READ_WRITE,MapMode.PRIVATE,通过名字可以看得出他们的作用,特别要注意MapMode.PRIVATE方法,如何你操作不当会导致你操作的文件无法被共享。
而position为区域内的文件映射的位置开始,必须是非负数
size为区域的大小是映射;必须是非负数,不大于Integer.MAX_VALUE
其实position和size的设置就意味着我们映射某个大文件的较小的部分
下面就来看我们使用了“映射文件访问”时,的性能提升把!
以下是代码部分:
package com.company; import java.io.*;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel; /**
* Created by chunmiao on 17-3-15.
*/
public class MappedIOTest {
//输入值的数量
private static int numOfInts = 4000000;
//测试读写值的数量大小
private static int numOfUbuffInts = 200000; private abstract static class Tester{
private String name;
public Tester(String name){
this.name = name;
} //测试计时
public void runTest(){
System.out.println(name + ": ");
try {
long start = System.nanoTime();
test();
long runtime = System.nanoTime() - start;
//输出test()运行时间,来判定操作时间大小
System.out.format("%.2f\n",runtime/1.0e9);
}catch (IOException e){
throw new RuntimeException(e);
}
} public abstract void test() throws IOException;
} private static Tester[] tests = {
//直接写入数据
new Tester("Stream Write") {
@Override
public void test() throws IOException {
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(new File("temp.tmp"))));
for (int i = 0; i < numOfInts; i ++){
dos.writeInt(i);
}
dos.close();
}
},
//使用MappedByteBuffer进行写文件操作
new Tester("Mapped Write") {
@Override
public void test() throws IOException {
FileChannel fc = new RandomAccessFile("temp.tmp","rw").getChannel();
//fc.size()返回的是以byte为单位的数量值。
IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE,0,fc.size()).asIntBuffer();
for(int i =0 ; i < numOfInts ; i ++){
try {
ib.put(i);
}catch (Exception e){
System.out.println(i);
}
}
fc.close();
}
},
//直接读数据
new Tester("Stream Read") {
@Override
public void test() throws IOException {
DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream("temp.tmp")));
for (int i = 0 ; i < numOfInts ; i ++){
dis.readInt();
}
dis.close();
}
},
//使用MappedByteBuffer进行读文件操作
new Tester("Mapped Read") {
@Override
public void test() throws IOException {
FileChannel fc = new FileInputStream(new File("temp.tmp")).getChannel();
IntBuffer ib = fc.map(FileChannel.MapMode.READ_ONLY,0,fc.size()).asIntBuffer();
while (ib.hasRemaining()){
ib.get();
}
fc.close();
}
},
//直接进行读/写操作
new Tester("Stream Read/Write") {
@Override
public void test() throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("temp.tmp"),"rw");
//对数据进行进行错位,以便同时进行读写操作
raf.writeInt(1);
for (int i = 0 ; i < numOfUbuffInts ; i ++){
//之所以减4的原因是raf.length()返回以byte为单位的空间大小,而1 (int) = 4 (byte),因此需要减4
raf.seek(raf.length() - 4);
raf.writeInt(raf.readInt());
}
raf.close();
}
},
//使用MappedByteBuffer进行读/写操作
new Tester("Mapped Read/Write") {
@Override
public void test() throws IOException {
FileChannel fc = new RandomAccessFile(new File("temp.tmp"),"rw").getChannel();
IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE,0,fc.size()).asIntBuffer();
ib.put(0);
for (int i = 1 ; i < numOfUbuffInts ; i ++){
//对数据进行进行错位,以便同时进行读写操作
ib.put(ib.get(i - 1));
}
fc.close();
}
}
}; public static void main(String[] args) {
//进行测试
for (Tester tester : tests){
tester.runTest();
}
}
}
以下是运行结果:

java利用“映射文件访问”(MapperByteBuffer)处理文件与单纯利用Buffer来处理文件的快慢比较的更多相关文章
- Linux中ls -l(ll)返回结果中的文件访问权限-rw-r--rw-
linux文件访问权限(像rw-r--rw-是什么意思) Linux的文件访问权限分为 读.写.执行三种 r:可读(4) w:可写(2)对目录来说则可新建文件 x:可执行(1)对目录来说则可进入该 ...
- 使用Java内存映射(Memory-Mapped Files)处理大文件
>>NIO中的内存映射 (1)什么是内存映射文件内存映射文件,是由一个文件到一块内存的映射,可以理解为将一个文件映射到进程地址,然后可以通过操作内存来访问文件数据.说白了就是使用虚拟内存将 ...
- java内存映射文件
内存映射文件能够让我们创建和修改大文件(大到内存无法读入得文件),对于内存映射文件,我们可以认为是文件已经全部被读入到内存当中,然后当成一个大的数字来访问,简化修改文件的代码. 1.directBuf ...
- java 编程基础:注解(Annotation Processing Tool)注解处理器 利用注解解读类属性生成XML文件
APT的介绍: APT(Annotation Processing Tool)是一种注解处理工具,它对源代码文件进行检测,并找出源文件所包含的注解信息,然后针对注解信息进行额外的处理. 使用APT工具 ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
- 全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件
作者: zyl910 一.缘由 RSA是一种常用的非对称加密算法.所以有时需要在不用编程语言中分别使用RSA的加密.解密.例如用Java做后台服务端,用C#开发桌面的客户端软件时. 由于 .Net.J ...
- CDN加速静态文件访问
CDN加速静态文件访问 全局调度 缓存技术 内容分发 带宽优化 CDN是Content Delivery Network的缩写,意思是内容分发网络.CDN的作用是把用户需要的内容分发到离用户近的地方, ...
- [apue] linux 文件访问权限那些事儿
前言 说到 linux 上的文件权限,其实我们在说两个实体,一是文件,二是进程.一个进程能不能访问一个文件,其实由三部分内容决定: 文件的所有者.所在的组: 文件对所有者.组用户.其它用户设置的权限访 ...
- Android开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制
一.需求 做一个类似QQ登录似的app,将数据写到ROM文件里,并对数据进行回显. 二.截图 登录界面: 文件浏览器,查看文件的保存路径:/data/data/com.amos.datasave/fi ...
随机推荐
- BZOJ2002(分块)
Bounce 弹飞绵羊 Time Limit:10000MS Memory Limit:265216KB 64bit IO Format:%lld & %llu Submit ...
- canvas小程序-快跑程序员
canvas不用说html5带来的好东西,游戏什么的,么么哒 记得有一天玩手机游戏,就是一个跳跃过柱子那种,其实元素很简单啊,app能开发,借助html5 canvas也可以啊, 于是就开始了. -- ...
- 编写JQuery插件-4
封装对象方法的插件 jQuery.fn.extend() 的两种写法 以添加一个点击按钮为例: 方法一: (function ($) { $.fn.mask = function(options){ ...
- java_JDBC(1)
Java连接Oracle步骤: 1.注册加载驱动 驱动名:DRIVER="oracle.jdbc.driver.OracleDriver";Class.forName(" ...
- salesforce 零基础学习(六十五)VF页面应善于使用变量和函数(一)常用变量的使用
我们在使用formula或者validation rules等的时候通常会接触到很多function,这些函数很便捷的解决了我们很多问题.其实很多函数也可以应用在VF页面中,VF页面有时候应该善于使用 ...
- Nginx工作原理
Nginx的模块 Nginx由内核和模块组成. Nginx的模块从结构上分为核心模块.基础模块和第三方模块: 核心模块:HTTP模块.EVENT模块和MAIL模块 基础模块:HTTP Access模块 ...
- 用JS计算预计时间与现在时间的差
1.我用的是bootstrap网格布局,首先要引入bootstrap类. (1)<script src="jquery-1.11.2.min.js"></scri ...
- 《经久不衰的Spring框架:SpringMVC 统括》
前言:经久不衰的Spring 这几年,前端技术更新换代速度之快,每一年"最火的前端技术"排行榜都会换一番场景,本当に信じかねる.是"只闻新人笑不见旧人哭",还是 ...
- django源码简析——后台程序入口
这一年一直在用云笔记,平时记录一些tips或者问题很方便,所以也就不再用博客进行记录,还是想把最近学习到的一些东西和大家作以分享,也能够对自己做一个总结.工作中主要基于django框架,进行项目的开发 ...
- 读书笔记 effective c++ Item 17 使用单独语句将new出来的对象放入智能指针
1. 可能会出现资源泄漏的一种用法 假设我们有一个获取进程优先权的函数,还有一个在动态分类的Widget对象上根据进程优先权进行一些操作的函数: int priority(); void proces ...