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

坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都混凝土搅拌罐车小微创业公司专业提供成都定制网页设计营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。
- 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
 
由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。
这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。