育路网学员服务电话:021-64691126

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

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

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

更多

更多上海计算机信息请访问:上海计算机培训网
上海计算机培训咨询电话:021-51602254
课程搜索:
免责声明
① 由于各方面情况不断调整与变化,育路网所提供的所有考试信息仅供参考,请考生以权威部门公布的正式信息为准。
② 本站注明稿件来源为其他媒体的文/图等稿件均为转载稿,本站转载出于非商业性的教育和科研之目的,并不意味着 赞同其观点或证实其内容的真实性。如转载稿涉及版权等问题,请作者在两周内速来电或来函联系。
③ 凡本站注明“稿件来源:上海育路网”的所有文字、图片和音视频稿件,版权均属本网所有,任何媒体、网站或个 人未经本网协议授权不得转载、链接、转贴或以其他方式复制发表。已经本站协议授权的媒体、网站,在下载使用时必 须注明“稿件来源:上海育路网”,违者本站将依法追究责任。
论坛话题
关于育路 | 企业理念 | 诚聘英才 | 商务合作 | 网站声明
全国免费热线:400-631-6616、021-51860462 邮箱:sh_yuloo#163.com (发送邮件时请将#换成@)
@2006-2016上海育路网络科技有限公司版权所有
网站备案:京ICP备10025267号-13 | 京公网安备110108904040号
友荐云推荐