`
serisboy
  • 浏览: 170063 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java中用内存映射处理大文件

    博客分类:
  • java
 
阅读更多
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。

package com.jiubang;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class Test {
	public static void main(String[] args) {
		try {
			FileInputStream fis = new FileInputStream(
					"/home/tobacco/test/res.txt");
			int sum = 0;
			int n;
			long t1 = System.currentTimeMillis();
			try {
				while ((n = fis.read()) >= 0) {
					sum += n;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			long t = System.currentTimeMillis() - t1;
			System.out.println("sum:" + sum + "  time:" + t);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			FileInputStream fis = new FileInputStream(
					"/home/tobacco/test/res.txt");
			BufferedInputStream bis = new BufferedInputStream(fis);
			int sum = 0;
			int n;
			long t1 = System.currentTimeMillis();
			try {
				while ((n = bis.read()) >= 0) {
					sum += n;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			long t = System.currentTimeMillis() - t1;
			System.out.println("sum:" + sum + "  time:" + t);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		MappedByteBuffer buffer = null;
		try {
			buffer = new RandomAccessFile("/home/tobacco/test/res.txt", "rw")
					.getChannel().map(FileChannel.MapMode.READ_WRITE, 0,
							1253244);
			int sum = 0;
			int n;
			long t1 = System.currentTimeMillis();
			for (int i = 0; i < 1253244; i++) {
				n = 0x000000ff & buffer.get(i);
				sum += n;
			}
			long t = System.currentTimeMillis() - t1;
			System.out.println("sum:" + sum + "  time:" + t);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
// 测试文件为一个大小为1253244字节的文件。测试结果:

sum:220152087 time:1464 
sum:220152087 time:72 
sum:220152087 time:25 说明读数据无误。删去其中的数据处理部分。

package com.jiubang;   
import java.io.BufferedInputStream;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.io.RandomAccessFile;  
import java.nio.MappedByteBuffer;  
import java.nio.channels.FileChannel;   
public class Test2 {             
	public static void main(String[] args) {          
		try {              
			FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");              
			int sum=0;              
			int n;              
			long t1=System.currentTimeMillis();              
			try {                  
				while((n=fis.read())>=0){                      
					sum+=n;                  
				}              
			} catch (IOException e) {                  
					// TODO Auto-generated catch block
				e.printStackTrace();              
			}              
			long t=System.currentTimeMillis()-t1;              
			System.out.println("sum:"+sum+"  time:"+t);          
		} catch (FileNotFoundException e) {              
			// TODO Auto-generated catch block
			e.printStackTrace();         
		}                    
		try {              
			FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");             
			BufferedInputStream bis=new BufferedInputStream(fis);              
			int sum=0;             
			int n;              
			long t1=System.currentTimeMillis();              
			try {                  
				while((n=bis.read())>=0){                      //
					sum+=n;                  
				}              
			} catch (IOException e) {                  
				// TODO Auto-generated catch
				// block
				e.printStackTrace();              
			}              
		long t=System.currentTimeMillis()-t1;              
		System.out.println("sum:"+sum+"  time:"+t);          
		} catch (FileNotFoundException e) {              // TODO Auto-generated
			// catch block
			e.printStackTrace();          
		}                    
		MappedByteBuffer buffer=null;          
		try {              
			buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244); 
			int sum=0;              
			int n;              
			long t1=System.currentTimeMillis();              
			for(int i=0;i<1253244;i++){                  // 
				n=0x000000ff&buffer.get(i);
				sum+=n;              
			}              
			long t=System.currentTimeMillis()-t1;              
			System.out.println("sum:"+sum+"  time:"+t);          
		} catch (FileNotFoundException e) {              // TODO
			e.printStackTrace();         
		} catch (IOException e) {              // TODO
			e.printStackTrace();          
		}       
	}   
} 
测试结果:

sum:0 time:1458 
sum:0 time:67 
sum:0 time:8
由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。

这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。

原文链接:http://blog.csdn.net/tobacco5648/article/details/7679105
分享到:
评论

相关推荐

    Java中用内存映射处理大文件的实现代码

    下面小编就为大家带来一篇Java中用内存映射处理大文件的实现代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    java源码包---java 源码 大量 实例

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    JAVA上百实例源码以及开源项目

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    java源码包4

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    java源码包3

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    JAVA上百实例源码以及开源项目源代码

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    java源码包2

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录 一个Java+ajax写的...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录 一个Java+ajax写的...

    双鱼林安卓Android代码生成器 v2.0.zip

    双鱼林基于安卓Android代码生成器是一款生成安卓手机程序的代码生成器 基于分层模式设计思想,生成的代码直接导入Eclipse软件就可以用的! ...res/drawable-mdpi:程序界面中用到的图片资源文件!

    asp.net知识库

    使用.ashx文件处理IHttpHandler实现发送文本及二进制数据的方法 制作一个简单的多页Tab功能 一完美的关于请求的目录不存在而需要url重写的解决方案! 在C#中实现MSN消息框的功能 XmlHttp实现无刷新三联动ListBox 鼠标...

    Visual C++ 2010入门经典(第5版)--源代码及课后练习答案

    6.4 处理内存分配错误 256 6.5 函数重载 257 6.5.1 函数重载的概念 258 6.5.2 引用类型和重载选择 260 6.5.3 何时重载函数 260 6.6 函数模板 261 6.7 使用decltype操作符 263 6.8 使用函数的示例 265 6.8.1...

    IBM WebSphere Portal门户开发笔记01

    2、本机域名映射 44 五、WCM几个页面路径及其名称 44 1、登录页面 44 2、主题及主页页面 45 3、皮肤外观页面路径 45 4、session超时页面 45 5、登录portal时,绕过登录界面,直接进入到主页(或再登录) 45 6、...

Global site tag (gtag.js) - Google Analytics