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"); } }
8.多线程文件拷贝(2)
最新推荐文章于 2023-06-28 07:29:36 发布