jdk8多线程操作文件

今天同事让我帮看看多线程读写文件,尝试着写了一个实例。操作的文件以块形式进行处理,块大小等于缓存大小,线程池根据cpu决定池大小。

/**
 * Created on 2016年3月18日
 */
package org.zl.test;

import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 文件以块形式进行处理,块大小等于缓存大小
 * 
 * 采用FileChannel的map方式读写文件
 * 线程池根据cpu决定池大小
 *  
 * <br>
 * change log:<br>
 * 0.01 2016年3月18日 Created <br>
 * @version 0.01
 * @author Leo
 */
public class FileRW {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		int bufferSize = 1024 * 1024;//块大小

		Path copy_from = Paths.get("d:\\web\\ajaxswing410.zip");
		//Path copy_from = Paths.get("d:\\license.txt");
		Path copy_to = Paths.get("d:\\data2.zip");
		//Path copy_to = Paths.get("d:\\l.txt");
		
		FileChannel fileChannel_from = FileChannel.open(copy_from,EnumSet.of(StandardOpenOption.READ));
		Files.deleteIfExists(copy_to);
		FileChannel fileChannel_to = FileChannel.open(copy_to,EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)); 
		ExecutorService executor = Executors.newWorkStealingPool();
		
		//分任务块
		long filesize = fileChannel_from.size();
		long bytesCount = 0;
		//List<Runnable> callables = Arrays.asList();
		while(filesize>bytesCount){
			long length=(filesize<(bytesCount+bufferSize))?filesize-bytesCount:bufferSize;
			Runnable task = new MyThread(fileChannel_from,fileChannel_to,bytesCount,length);
			executor.submit(task);
			bytesCount = bytesCount+bufferSize;
		}
		
		//线程结束关闭通道
		while(!executor.isShutdown()){
			executor.shutdown();
			TimeUnit.SECONDS.sleep(2);
		}
		fileChannel_from.close();
		fileChannel_to.close();
	}

}
class MyThread implements Runnable{

	FileChannel fileChannel_from;
	FileChannel fileChannel_to;
	long offset;
	int length;
	
	
	/**
	 * 
	 * @param fileChannel_from 读通道
	 * @param fileChannel_to 写通道
	 * @param offset 起点
	 * @param length 长度
	 */
	public MyThread(FileChannel fileChannel_from,FileChannel fileChannel_to,long offset,long length) {
		this.fileChannel_from =fileChannel_from;
		this.fileChannel_to =fileChannel_to;
		this.offset=offset;
		this.length=Long.valueOf(length).intValue();
	}
	
		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			long startTime = System.nanoTime();
			//ByteBuffer bytebuffer = ByteBuffer.allocate(length);
			//ByteBuffer bytebuffer = ByteBuffer.allocateDirect(TestThread.bufferSize);
			//bytebuffer.flip();
			try {
				System.out.println("read:"+length);
				//fileChannel_from.read(bytebuffer, offset);
				MappedByteBuffer buffer = fileChannel_from.map(FileChannel.MapMode.READ_ONLY,offset,length);
				fileChannel_to.write(buffer,offset);
				
				//bytebuffer.clear();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		    String threadName = Thread.currentThread().getName();
		    long elapsedTime = System.nanoTime() - startTime;
		    System.out.println(threadName+" Elapsed Time is " + (elapsedTime / 1000000000.0) + " seconds");
		}
	
}



程序只做为测试,不够严谨。欢迎提意见和改进想法,看看java新特性是否能提供更便捷的代码操作。

猜你喜欢

转载自l7980.iteye.com/blog/2284630