Java中用内存映射处理大文件
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。
- package test;
- 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 test;
- 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();
- }
- }
- }
测试结果:
sum:0 time:1458
sum:0 time:67
sum:0 time:8
由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。
这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。
Java中用内存映射处理大文件的更多相关文章
- Java使用内存映射实现大文件的上传
在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如 ...
- Delphi 中内存映射对于大文件的使用
这篇文章主要介绍了Delphi 中内存映射对于大文件的使用的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下 Delphi 中内存映射对于大文件的使用 平时很少使用大文件的内存映射,碰巧遇到了 ...
- Java NIO内存映射---上G大文件处理(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了java中内存映射的原理及过程,与传统IO进行了对比,最后,用实例说明了结果 ...
- Java NIO 内存映射文件
Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...
- Java利用内存映射文件实现按行读取文件
我们知道内存映射文件读取是各种读取方式中速度最快的,但是内存映射文件读取的API里没有提供按行读取的方法,需要自己实现.下面就是我利用内存映射文件实现按行读取文件的方法,如有错误之处请指出,或者有更好 ...
- JAVA NIO 内存映射(转载)
原文地址:http://blog.csdn.net/fcbayernmunchen/article/details/8635427 Java类库中的NIO包相对于IO 包来说有一个新功能是内存 ...
- 如何设置Java虚拟机内存以适应大程序的装载
Java虚拟机对于运行时的程序所占内存是有限制的,当我们的项目或者程序很大时,往往会照成内存溢出. 举个例子: public class SmallTest1 { public static void ...
- java 通过内存映射文件来提高IO读取文件性能
MappedByteBuffer out = new RandomAccessFile("src/demo20/test.dat", "rw"). getCha ...
- php 如何在有限的内存中读取大文件
突然遇到了一个要读取超过80M文件的需求,很悲剧的,不管是file_get_content还是file什么的,都会将读取的文件一次性加载到内存中. 正常情况下,我们可以使用fseek来读取,好处就是不 ...
随机推荐
- 帝国cmsV6.6版数据表
信息表:每个模型都有以下六个表 phome_ecms_news 新闻系统模型-主表 phome_ecms_news_data_1 新闻系统模型-副表1 副表可无限增加 信息表 phome_ecms_n ...
- js页面用定时任务通过AJAX获取后台数据,但是从这个页面跳转到其他页面后,定时任务仍然在定时请求后台
setInterval(function(){//ajax 请求后台数据},1000);这个是A页面的定时器然后我在A页面通过其他请求跳转到其他页面之后后台发现A页面的定时器的那个请求仍然在执行为什么 ...
- vim 使用说明
=========================================================本使用说明与 把VIM打造成IDE 配套======================= ...
- 框架SpringMVC笔记系列 一 基础
主题:SpringMVC 学习资料参考网址: 1.http://www.icoolxue.com 2.http://aokunsang.iteye.com/blog/1279322 1.SpringM ...
- NOSQL学习笔记系列之MongoDB 一 基础
主题:MongoDB 学习资料参考网址: 1.http://www.w3cschool.cc/mongodb/mongodb-tutorial.html 2.http://www.icoolxue.c ...
- 泛函编程(37)-泛函Stream IO:通用的IO处理过程-Free Process
在上两篇讨论中我们介绍了IO Process:Process[I,O],它的工作原理.函数组合等.很容易想象,一个完整的IO程序是由 数据源+处理过程+数据终点: Source->Process ...
- Spring中的通知(Advice)和顾问(Advisor)
在Spring中,目前我学习了几种增强的方式,和大家分享一下 之前的话: 1.AOP (Aspect Oriented Programming 面向切面编程) 在软件业,AOP为Aspect O ...
- [javascript] 判断 iframe 是否加载完成
from http://www.planabc.net/2009/09/22/iframe_onload/ var iframe = document.createElement("ifra ...
- PHP 单例模式继承的实现方式
/** * @author xiaojiang * 方式1 */ class father{ static $models = []; static public function getInstan ...
- Sequence.js 实现带有视差滚动特效的图片滑块
Sequence.js 功能齐全,除了能实现之前分享过的现代的图片滑动效果,还可以融合当前非常流行的视差滚动(Parallax Scrolling)效果.让多层背景以不同的速度移动,形成立体的运动效果 ...