8.多线程文件拷贝(2)

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

class MyTask implements Callable<Long>{
	private RandomAccessFile src;
	private RandomAccessFile des;
	//在每个线程中写文件的时候,都需要实例化一个RandomAccessFile的实例,
	//而不能重复使用同一个RandomAccessFile
	private int id;
	private long curSendSize;
	
	public MyTask(File src, File des, int i) throws FileNotFoundException{
		this.src = new RandomAccessFile(src, "r");
		this.des = new RandomAccessFile(des, "rw");
		this.id = i;
		this.curSendSize = 0;
	}
	
	public Long call(){
		try {
			
			src.seek(id*TestDemo.BLOCK_SIZE);   //读写指针移动到对应位置
			des.seek(id*TestDemo.BLOCK_SIZE);
			
			long count;
			byte[] buff = new byte[4096];
			while ((count = src.read(buff)) > 0){	
				des.write(buff);
				curSendSize += count;
				if ((curSendSize+4096) > TestDemo.BLOCK_SIZE){
					byte[] newBuff = new byte[(int) (TestDemo.BLOCK_SIZE-curSendSize)];
					src.read(newBuff);
					des.write(newBuff);
					return (long) TestDemo.BLOCK_SIZE;
				}
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			
			try {
				if (src != null){
					src.close();
				}
				if (des != null){
					des.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
		}
		return curSendSize;
	}
}

public class TestDemo {
	public static final int BLOCK_SIZE = 30*1024*1024; //文件分块,30M为一个线程
	private static ArrayList<Future<Long>> list;  //存储每一个线程提交之后返回的Future对象
	private static ExecutorService threadpool;
	
	static{
		list = new ArrayList<Future<Long>>();
	}

	public static void main(String[] args) throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		
		System.out.println("input filename:");
		Scanner scan = new Scanner(System.in);
		String filename = scan.nextLine();
		File src = new File(filename);
		if (!src.exists()){
			System.out.println("file not exit!");
			System.exit(1);
		}
		
		String[] fileDir = filename.split("/");
		StringBuilder newFileName = new StringBuilder("D:/");
		newFileName.append(fileDir[fileDir.length-1]);//默认目标文件"D:/"+文件名称
		File des = new File(newFileName.toString());
		if (!des.exists()){
			des.createNewFile();
		}
		
		long begin = System.currentTimeMillis();
		long fileSize = src.length();
		int threadCount = (int) (fileSize/BLOCK_SIZE) + 1; //根据文件大小分配线程数量
		
		System.out.println("filesize:" + fileSize);
		System.out.println("threadCount:" + threadCount);
		
		threadpool = Executors.newFixedThreadPool(threadCount);  //创建固定数量线程的线程池
		
		for (int i = 0; i < threadCount; ++i){
			list.add(threadpool.submit(new MyTask(src, des, i)));
		}
		
		System.out.println("wait file read and write...");
		long recvSize = 0;
		try {
			for (Future<Long> future : list){
				recvSize += future.get();  //得到每隔线程的返回值,若线程为结束,主线程会阻塞
			}
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("recvSize:" + recvSize);
		threadpool.shutdown();	
		
		long end = System.currentTimeMillis();
		System.out.println("spend time:" + (end-begin) + "s");
		System.out.println("main over");
	}

}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值