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 ...
随机推荐
- 小试 Ninja
Ninja 是最近冒出来的一个 build system,它很像 make,然而效率更高,对大项目支持更好.当然我用 Ninja 和效率无关(我又没有那种有几百个中间目标的 C++ 项目要 build ...
- Clojure发音
Clojure的发音和单词closure是一样的.Clojure之父是这样解释Clojure名字来历的 “我想把这就几个元素包含在里面: C (C#), L (Lisp) and J (Java). ...
- Nancy简单实战之NancyMusicStore(四):实现购物车
前言 上一篇,我们完成了商品的详情和商品的管理,这一篇我们来完成最后的一个购物车功能. 购物车,不外乎这几个功能:添加商品到购物车,删除购物车中的商品,对购物车中的商品进行结算. MVC MusicS ...
- HDU2579
Dating with girls(2) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- codeforces div2.C
C. New Year and Rating time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- python爆破定长密码脚本
def get_pwd(str, num):#str为可选字符集,num为密码长度 if(num == 1): for x in str: yield x else: for x in str: fo ...
- 初识 BFC、 IFC、GFC、FFC
首先本文中介绍的 BFC. IFC.GFC.FFC 均为 CSS 中常见问题的解读,如没兴趣,可以绕道了. 然后在介绍这么多的 *FC 之前,我们得了解 一下 Box 和 Formatting Con ...
- 10步完成Abp(.net core)+Vue的Demo?
1.去abp官网生成项目,选择.net core1.x版本 2.Nuget还原包,需装dotnet core1.1等. 3.新增一个entity,并加入到上下文中 4.然后cmd命令行工具切换到项目 ...
- 百度云推送----iOS
前言 记录一下这几天学习的百度推送,觉得这个东西弄的还挺糟心的,好多注意的地方 正文 1.先申请一个百度开发者账号 http://push.baidu.com/fc 2.创建一个新应用,并应用配置 3 ...
- Github windows客户端简单上手教程
作为一个前端,如果不知道GitHub,那你有可能就是一个假前端(O(∩_∩)O哈哈~)开个玩笑...进入正题,咳咳... 1.第一步要在GitHub官网下载最新的客户端,网址是https://desk ...