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

来源:互联网 发布:王路 知乎 编辑:程序博客网 时间:2024/05/18 13:44
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的实例,//而不能重复使用同一个RandomAccessFileprivate 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 blocke.printStackTrace();} finally{try {if (src != null){src.close();}if (des != null){des.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.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 stubSystem.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 blocke.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
原创粉丝点击