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

来源:上海计算机考试网 时间:2013-11-21

  在处理大文件时,如果利用普通的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

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

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

本文结束

特别声明:①凡本网注明稿件来源为"原创"的,转载必须注明"稿件来源:上海育路网",违者将依法追究责任;

②部分稿件来源于网络,旨在与用户分享信息,如有侵权,请联系我们沟通解决。

有用

25人觉的有用

阅读全文

课程报名登记

课程 :
服务需求 :
姓名 :
联系方式 :

《隐私保障》

课程咨询电话:021-51602254、400-058-1158

相关文章推荐

29

2019.11

上海PHP动态网页开发工程师零基础班招生简章

上海非凡学院作为沪上PHP动态网页开发工程师培训课程正规培训基地,具有办学许可证,全程名师面授教学,PPHA教学考核体系,毕业答辩+招聘双选会,为国内外知名品牌企业提供优秀专业设计人才!......

28

2015.10

ORM一键还原系统使用教程

  ORM一键还原系统,是用于备份和还原Windows操作系统的软件,下面育路_上海计算机培训网给大家介绍该工具的使得方法  ORM一键还原系统使用教程  一、安装  双击ORM_Setup.exe文件,您将看到如下界面,点击&......

28

2015.10

有些网站打不开怎么办?

  有些网站打不开怎么办?有些朋友遇到了了一个很奇怪的问题: 一些网站打不开?大多数人会认为是服务器问题,但通过ping服务器IP一切正常,并且使用IP地址可以访问网站。但输入网址却打不开网站。更奇怪的是自己打不......

28

2015.10

Win8应用商店打不开该怎么解决?

  Win8应用商店里有很多好用的软件,但是国内用户有时会打不开Win8商店,下面育路_上海计算机培训网就来说说解决方法  首先,得确保你的网络是连通的,没有问题  一、修改DNS的方法:  使用谷歌提供的免费DN......

28

2015.10

在Linux下利用mencoder将视频里的音频提取出来

  大家都习惯于使用Windows系统。因为毕竟Linux有点专业。我们普通人大多电脑的专业知识有限。我们在Windows系统下,一般会用转换软件或播放软件另存为的方法保存视频里面的音频。Linux下可以利用mencoder将视频里......

28

2015.10

Linux操作系统软件安装方法

  Linux操作系统与Windows系统一样,装了系统的第一件事必然是装常用的软件,Linux集成了不少软件,可是对于一些习惯了的 windows文件兼容性不太好,所以还是要下一些比较全面的软件或代替或补充。Linux下安装软件......

您可能感兴趣
少儿英语机构 上海对外交流中心海外留学落户定向班 上海优质国际高中教育展 中外合作办学免联考硕士 上海自考本科培训