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

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

坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都混凝土搅拌罐车小微创业公司专业提供成都定制网页设计营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。

 
 
 
  1. package test;  
  2.  
  3. import java.io.BufferedInputStream;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.IOException;  
  7. import java.io.RandomAccessFile;  
  8. import java.nio.MappedByteBuffer;  
  9. import java.nio.channels.FileChannel;  
  10.  
  11. public class Test {  
  12.  
  13.       
  14.     public static void main(String[] args) {  
  15.         try {  
  16.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  17.             int sum=0;  
  18.             int n;  
  19.             long t1=System.currentTimeMillis();  
  20.             try {  
  21.                 while((n=fis.read())>=0){  
  22.                     sum+=n;  
  23.                 }  
  24.             } catch (IOException e) {  
  25.                 // TODO Auto-generated catch block  
  26.                 e.printStackTrace();  
  27.             }  
  28.             long t=System.currentTimeMillis()-t1;  
  29.             System.out.println("sum:"+sum+"  time:"+t);  
  30.         } catch (FileNotFoundException e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         }  
  34.           
  35.         try {  
  36.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  37.             BufferedInputStream bis=new BufferedInputStream(fis);  
  38.             int sum=0;  
  39.             int n;  
  40.             long t1=System.currentTimeMillis();  
  41.             try {  
  42.                 while((n=bis.read())>=0){  
  43.                     sum+=n;  
  44.                 }  
  45.             } catch (IOException e) {  
  46.                 // TODO Auto-generated catch block  
  47.                 e.printStackTrace();  
  48.             }  
  49.             long t=System.currentTimeMillis()-t1;  
  50.             System.out.println("sum:"+sum+"  time:"+t);  
  51.         } catch (FileNotFoundException e) {  
  52.             // TODO Auto-generated catch block  
  53.             e.printStackTrace();  
  54.         }  
  55.           
  56.         MappedByteBuffer buffer=null;  
  57.         try {  
  58.             buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);  
  59.             int sum=0;  
  60.             int n;  
  61.             long t1=System.currentTimeMillis();  
  62.             for(int i=0;i<1253244;i++){  
  63.                 n=0x000000ff&buffer.get(i);  
  64.                 sum+=n;  
  65.             }  
  66.             long t=System.currentTimeMillis()-t1;  
  67.             System.out.println("sum:"+sum+"  time:"+t);  
  68.         } catch (FileNotFoundException e) {  
  69.             // TODO Auto-generated catch block  
  70.             e.printStackTrace();  
  71.         } catch (IOException e) {  
  72.             // TODO Auto-generated catch block  
  73.             e.printStackTrace();  
  74.         }  
  75.  
  76.     }  
  77.  
  78. }  

测试文件为一个大小为1253244字节的文件。测试结果:

 
 
 
  1. sum:220152087 time:1464  
  2. sum:220152087 time:72  
  3. sum:220152087 time:25 

说明读数据无误。删去其中的数据处理部分。

 
 
 
  1. package test;  
  2.  
  3. import java.io.BufferedInputStream;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.IOException;  
  7. import java.io.RandomAccessFile;  
  8. import java.nio.MappedByteBuffer;  
  9. import java.nio.channels.FileChannel;  
  10.  
  11. public class Test {  
  12.  
  13.       
  14.     public static void main(String[] args) {  
  15.         try {  
  16.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  17.             int sum=0;  
  18.             int n;  
  19.             long t1=System.currentTimeMillis();  
  20.             try {  
  21.                 while((n=fis.read())>=0){  
  22.                     //sum+=n;  
  23.                 }  
  24.             } catch (IOException e) {  
  25.                 // TODO Auto-generated catch block  
  26.                 e.printStackTrace();  
  27.             }  
  28.             long t=System.currentTimeMillis()-t1;  
  29.             System.out.println("sum:"+sum+"  time:"+t);  
  30.         } catch (FileNotFoundException e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         }  
  34.           
  35.         try {  
  36.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  37.             BufferedInputStream bis=new BufferedInputStream(fis);  
  38.             int sum=0;  
  39.             int n;  
  40.             long t1=System.currentTimeMillis();  
  41.             try {  
  42.                 while((n=bis.read())>=0){  
  43.                     //sum+=n;  
  44.                 }  
  45.             } catch (IOException e) {  
  46.                 // TODO Auto-generated catch block  
  47.                 e.printStackTrace();  
  48.             }  
  49.             long t=System.currentTimeMillis()-t1;  
  50.             System.out.println("sum:"+sum+"  time:"+t);  
  51.         } catch (FileNotFoundException e) {  
  52.             // TODO Auto-generated catch block  
  53.             e.printStackTrace();  
  54.         }  
  55.           
  56.         MappedByteBuffer buffer=null;  
  57.         try {  
  58.             buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);  
  59.             int sum=0;  
  60.             int n;  
  61.             long t1=System.currentTimeMillis();  
  62.             for(int i=0;i<1253244;i++){  
  63.                 //n=0x000000ff&buffer.get(i);  
  64.                 //sum+=n;  
  65.             }  
  66.             long t=System.currentTimeMillis()-t1;  
  67.             System.out.println("sum:"+sum+"  time:"+t);  
  68.         } catch (FileNotFoundException e) {  
  69.             // TODO Auto-generated catch block  
  70.             e.printStackTrace();  
  71.         } catch (IOException e) {  
  72.             // TODO Auto-generated catch block  
  73.             e.printStackTrace();  
  74.         }  
  75.  
  76.     }  
  77.  

测试结果:

 
 
 
  1. sum:0 time:1458  
  2. sum:0 time:67  
  3. sum:0 time:8 

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

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

标题名称:Java中用内存映射处理大文件
网页地址:http://www.hantingmc.com/qtweb/news8/229908.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联