JAVA NIO文件映射、通道、流读写文件示例

2014-11-24 02:45:35 · 作者: · 浏览: 0

本例使用FileChannel和 BufferedInputStream等测试对比。


TestHandler.java 用于实现动态代理,测试运行效率

package com.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TestHandler implements InvocationHandler{

	private Object obj=null;
	
	public TestHandler(Object obj){
		this.obj=obj;
	}
	
	public static Object newInstance(Object obj){
		Object result=Proxy.newProxyInstance(obj.getClass().getClassLoader(),
				obj.getClass().getInterfaces(), new TestHandler(obj));
		return result;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result=null;
		System.out.println("执行中...");
		
		long start=System.currentTimeMillis();
		result=method.invoke(obj, args);
		
		long end=System.currentTimeMillis();
		System.out.println("执行完成,耗时:"+(end-start));
		
		return result;
	}

}

INIOTest.java

package com.test;

import java.io.IOException;

public interface INIOTest{
	public void copyFileMapped(String oldPath,String newPath)  throws IOException;
	public void copyFileNIO(String oldPath,String newPath)  throws IOException;
	public void copyFile(String oldPath,String newPath)  throws IOException;
}


Test.java

package com.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;


public class Test implements INIOTest{
	public void copyFileMapped(String oldPath,String newPath)  throws IOException{
		long length=0;
		RandomAccessFile raf=new RandomAccessFile(oldPath , "r");
		FileChannel fcr=raf.getChannel();
		length=fcr.size();
		//返回要读取文件的映射内存区块
		MappedByteBuffer mbb=fcr.map(FileChannel.MapMode.READ_ONLY, 0, length);
		ByteBuffer buffer=mbb.get(new byte[(int)length]);
		
		//要写入的文件
		RandomAccessFile raw=new RandomAccessFile(newPath, "rw");
		FileChannel fcw=raw.getChannel();
		MappedByteBuffer mbbw=fcw.map(FileChannel.MapMode.READ_WRITE, 0, length);
		for(int i=0;i
  
   

第一个为使用文件映射读写耗时

第二个为文件通道(Channel)读写文件耗时

第三个位BufferedInputStream等耗时


测试多次均是Channel,文件映射读写耗时较稳定,时间也比较短,BufferedInputStream时间也不错,和映射差不多(个人测试的是180M的文件,大文件建议还是使用文件映射可能好点)


特别需要注意的是文件映射无法关闭,MappedByteBuffer是java平台共享内存的实现,把硬盘虚拟为内存,主要用于进程间共享数据,所以在进程没有退出前文件是不允许删除的。也无法访问它。所以这里将它置为null,并等待垃圾回收它。


参考:http://yipsilon.iteye.com/blog/298153