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 ...
随机推荐
- Flex移动皮肤开发(二)
范例文件 mobile-skinning-part2.zip 在这个讨论创建 Flex 移动 skin 的系列的 第 1 部分 中,我讨论了 Flex 团队在 Mobile 主题中所做的性能优化的原理 ...
- 在MyEclipse 2014中给Spket增加ExtJS提示
参考:http://wenku.baidu.com/link?url=BT2U6Z-HktQJQYpz3Jp88pJSp4lU-lXkvCqpdeaa9a-BVdOgMGK1vj486-32YC4Gq ...
- 老司机教你下载tumblr上视频和图片的正确姿势
本文面向初学者. 很多同学问我:“我非常想学Python编程,但是找不到兴趣点”. 还有的同学呢,找到了很好的兴趣点,但是无从下手,“玄魂老师,我想下载tumblr上的视频, 怎么下载,Python能 ...
- editormd使用教程
对于现在的程序员来说,都需要一个快速写文章的语言,那么无非就是markdown了,市面上markdown编辑器并不多,而且也不怎么好用,现在推荐国内的比较牛逼的. 入门 建议先到官方看下如何使用,避免 ...
- 【费式数列(Fibonacci数列)】
/* 说明: Fibonacci为1200年代的欧洲数学家,在他的着作中曾经提到:若有一只兔子每个月生一只小兔子,一个月后也开 始生产.起初只有一只兔子,一个月后就有两只兔子,二个月后就有三只兔子,三 ...
- java_XML_JAXB
JAXB 可以实现Java对象与XML的相互转换,在JAXB中,将一个Java对象转换为XML的过程称之为Marshal,将XML转换为Java对象的过程称之为UnMarshal. 下面使用的是JDK ...
- 扩展jquery插件的方法
方法1.通过一个简单的.jQuery函数prototype属性的别名(jquery.fn进行扩展) jQuery.fn.newStuff = function(){ console.log(" ...
- node.js 的事件机制
昨天到今天, 又看了一边node 的事件模块, 觉得很神奇~ 分享一下 - -> 首先, 补充下对node 的理解: nodeJs 是一个单进程单线程应用程序, 但是通过事件和回调支持并发 ...
- 走进javascript——DOM事件
DOM事件模型 在0级DOM事件模型中,它只是简单的执行你为它绑定的事件,比如你为某个元素添加了一个onclick事件,当事件触发时,它只是去调用我们绑定的那个方法,不再做其他的操作. 在2级DOM事 ...
- 配置IIS Express以便通过IP地址访问调试的网站
问题背景 最近使用C#编写了一个WebService,希望通过Java进行调用.使用Visual Studio 2013调试WebService时,可以在浏览器中通过localhost地址访问WSDL ...