NIO中的内存映射文件使用对效率提高的验证

         对比较大的而不能放入内存的文件进行I/O操作时,如果使用NIO中的内存映射文件对性能效率和速度的提高是非常显著的。首先需要获取文件的通道,然后调用通道的map(FileChannel.MapMode mode,long position,long size)函数将文件从position位置开始的长度为size的内容映射到内存中。具体的效率比较代码示例如下:

       

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;

//测试代码是借用thingking in java中的
public class MappedIO {
	
	//先声明需要写入的文件的内容的大小
	private static final int NUMOFINT=4000000;
	private static final int NUMOFOUT=2000000;
	
	//测试类,用来测试使用普通的I/O操作和使用内存文件映射时速度的差别
	abstract static class Tester{
		private String name;
		public Tester(String name){
			this.name=name;
		}
		
		public void runTest(){
			System.out.println("使用"+name+"所消耗的时间:");
			try{
		    //以毫微秒为单位获取测试函数开始前的时间
			long begin=System.nanoTime();
			
			test();
			//将测试函数结束后的系统的时间减去开始之前的时间获取
			double duration=System.nanoTime()-begin;
			//PrintStream中的使用指定格式字符串和参数将格式化字符串写入此输出流中的方法
			System.out.format("%.2f\n", duration/1.0e9);
			}catch(IOException e){
				e.printStackTrace();
			}
		}
		
		//具体的测试函数中其实不仅有对文件进行读取或写入的时间,还包括消耗的各种初始化I/O对象的时间,而且内存映射文件的初始化对象消耗更要比普通的操作大
		public abstract void test() throws IOException;
	}
	
	private static Tester[] tests={
		//先使用普通的stream write,并且还是用了Buffered缓冲
		new Tester("stream write"){
			public void test()throws IOException{
				DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("baolei.txt"))); 
			    for(int i=0;i<NUMOFINT;i++){
			    	dos.writeInt(i);
			    }
			    dos.close();
			}
		},
		//使用内存映射文件方式写入文件时的测试内部类
		new Tester("mapped write"){
			public void test() throws IOException{
				//利用RandomAccessFile初始化文件获取通道
				FileChannel fc=new RandomAccessFile("baolei.txt","rw").getChannel();
				//利用IntBuffer基本类型视图缓冲器来修改底层的ByteBuffer,实际上ByteBuffer是将数据移进移出通道的唯一方式
				IntBuffer ib=fc.map(FileChannel.MapMode.READ_WRITE, 0,fc.size()).asIntBuffer();
				for(int i=0;i<NUMOFINT;i++){
					ib.put(i);
				}
				
				fc.close();
			}
		},
		
		//下面的两个测试方法是测试read文件时的速度,基本和上面的两个一样
		new Tester("stream read"){
			public void test()throws IOException{
				DataInputStream dis=new DataInputStream(new BufferedInputStream(new FileInputStream("baolei.txt")));
				
				for(int i=0;i<NUMOFOUT;i++){
					dis.readInt();
				}
				dis.close();
			}
		},
		new Tester("mapped read"){
			public void test() throws IOException{
				FileChannel fc=new RandomAccessFile("baolei.txt","rw").getChannel();
				IntBuffer ib=fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()).asIntBuffer();
				while(ib.hasRemaining()){
					ib.get();
				}
				
				fc.close();
			}
		}

	};
	
	public static void main(String[] args){
		for(Tester test:tests){
			test.runTest();
		}
	}

}

 

   可以看到运行后的结果如下:

           使用stream write所消耗的时间:
           0.92
          使用mapped write所消耗的时间:
           0.12
          使用stream read所消耗的时间:
           0.50
         使用mapped read所消耗的时间:
           0.06
    效率确实大幅度提高啊。

     

 

          

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值