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 ...
随机推荐
- React Router基础使用
React是个技术栈,单单使用React很难构建复杂的Web应用程序,很多情况下我们需要引入其他相关的技术 React Router是React的路由库,保持相关页面部件与URL间的同步 下面就来简单 ...
- TCP/IP协议族(一) HTTP简介、请求方法与响应状态码
接下来想系统的回顾一下TCP/IP协议族的相关东西,当然这些东西大部分是在大学的时候学过的,但是那句话,基础的东西还是要不时的回顾回顾的.接下来的几篇博客都是关于TCP/IP协议族的,本篇博客就先简单 ...
- 玩转 Ceph 的正确姿势
玩转 Ceph 的正确姿势 本文先介绍 Ceph, 然后会聊到一些正确使用 Ceph 的姿势:在集群规模小的时候,Ceph 怎么玩都没问题:但集群大了(到PB级别),这些准则可是保证集群健康运行的不二 ...
- 日志组件 logback
一.简介 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- classic和logback-access.logb ...
- 蓝牙门禁Android客户端
先来了解下Android传统蓝牙连接的大致简单的流程: 其中涉及到几个类依次来介绍,废话不多说,下面是从Android4.4开发指南蓝牙所用到的类的截图: 第一个类BluetoothAdapter: ...
- pyqt的 .ui 转换为 .py 后的操作注意事项
1. 增加 import sys 2. 将 Ui_MainWindow(object) 中的 object 修改成修改成 QtGui.QMainWindow 3. 在 Ui_MainWindow 类中 ...
- [Linux] - Linux下安装jdk,tar方式
下载jdk的linux下版本,下载页面http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.ht ...
- Javascript面对对象. 第一篇
Javascript,有两个种开发模式: 1.函数式(过程化)2.面对对象(oop),面对对象语言有一个标志,就是类,而通过类可以创建任何多个属性和方法,而Ecmascript没有类的概念,因此它的对 ...
- weex官方demo weex-hackernews代码解读(1)
一.介绍 weex 是阿里出品的一个类似RN的框架,可以使用前端技术来开发移动应用,实现一份代码支持H5,IOS和Android.最新版本的weex已默认将vue.js作为前端框架,而weex-hac ...
- php编译安装
php编译安装含mcrypt扩展 开始前准备 1.php源码下载 这里用的是php5.6.22版本 wget -c http://cn2.php.net/get/php-5.6.22.tar.gz/f ...