关于多线程,大家可以看下这个博客
https://www.cnblogs.com/dolphin0520/p/3932921.html
真心不错。
下面直接贴我自己写的多线程实现文件拷贝的代码。
package util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class DownLoadFile implements Runnable { public static int srcFileSize; // 原文件大小 public static int threadNum = 5; // 线程数 public static ExecutorService executorService = Executors.newFixedThreadPool(threadNum); private String url; //源文件路径 private String dst; //目标文件路径 private int start; //开始下载位置 private int end; //结束下载位置 public DownLoadFile() { super(); // TODO Auto-generated constructor stub } public DownLoadFile(String url, String dst, int start, int end) { super(); this.url = url; this.dst = dst; this.start = start; this.end = end; } /** * * @param url 要拷贝的文件 * @param dst 拷贝到哪儿 * @return * @throws IOException */ private void DownLoad(String url,String dst) throws IOException{ // 获取原文件总大小 FileInputStream fileInputStream = new FileInputStream(url); srcFileSize = fileInputStream.available(); fileInputStream.close(); // 获取每个线程需要复制的字节大小 int partSize = srcFileSize/threadNum; // 目的文件夹如果不存在,则创建 File dstFile = new File(dst); if(!dstFile.exists()){ dstFile.createNewFile(); } // 启用threadNum个线程进行复制文件 for(int i=0;i<threadNum;i++){ int start = partSize * i; int end = (i==(threadNum-1))?srcFileSize:partSize*(i+1); DownLoadFile dLF = new DownLoadFile(url, dst, start, end); executorService.execute(dLF); } executorService.shutdown(); } //执行拷贝 public void run() { System.out.println("start:" + start + " end:" + end ); try { String threadName = Thread.currentThread().getName(); // 线程名 System.out.println("线程"+threadName+"开始拷贝文件数据,拷贝数据段:"+start+"-"+end); // 定位目标文件位置 RandomAccessFile randomAccessFile = new RandomAccessFile(dst, "rw"); randomAccessFile.seek(start); // 定位原文件位置 InputStream inputStream = new FileInputStream(url); inputStream = skipFully(inputStream,start); // 复制文件内容 int sumSize = end - start; // 复制总字节数 int readSize = 1024*1024*8; // 缓存8MB while(sumSize>0){ // 缓存大于拷贝字节,使用拷贝字节 if(readSize>sumSize){ readSize = sumSize; } // 从原文件输入流获取拷贝字节数据 byte[] tmp = new byte[readSize]; inputStream.read(tmp); // 向目标文件写入拷贝字节数据 randomAccessFile.write(tmp); sumSize -= readSize; } // 拷贝完毕后,双方都关闭 inputStream.close(); randomAccessFile.close(); System.out.println("线程"+threadName+"拷贝数据结束,数据段:"+start+"-"+end); } catch (Exception e) { e.printStackTrace(); } } public static InputStream skipFully(InputStream in,long num)throws Exception{ long remainning = num; long len = 0; while(remainning>0){ len = in.skip(num); remainning -= len; } return in; } public static void main(String args[]) { DownLoadFile d = new DownLoadFile(); try { d.DownLoad("D:\\1.exe","D:\\\\1_copy.exe"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }