多线程下载或者复制文件 - 日理万妓 2022-11-21 14:42 119阅读 0赞 # 1,核心类 # RandomAccessFile # 2,核心思想 # * a)在目标处建立一个和源文件大小一致的空文件。 //File file = new File("/Users/waynezhao/Downloads/PCQQ2020.exe"); File file = new File("/Users/waynezhao/Downloads/temp.log"); RandomAccessFile ref = new RandomAccessFile(file,"rws"); ref.setLength(contentLength);//设置下载之后的文件大小 ref.close(); * b)开启线程下载 对于网络文件,可以在请求属性中增加 Range属性,读取文件的位置。 对于要复制文件,则可以使用RandomAccessFile,来随机读取文件。 代码如下 //HttpURLConnection connection = (HttpURLConnection)url.openConnection(); //connection.setRequestProperty("Range","bytes="+threadStart+"-"+threadEnd); //InputStream inputStream = connection.getInputStream(); RandomAccessFile oriRandomAccessFile = new RandomAccessFile(oriFile, "r"); oriRandomAccessFile.seek(threadStart); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rws"); randomAccessFile.seek(threadStart); byte[] buffer = new byte[1024]; int len; //while((len = inputStream.read(buffer)) != -1){ while((len = oriRandomAccessFile.read(buffer)) != -1){ randomAccessFile.write(buffer,0,len); } randomAccessFile.close(); oriRandomAccessFile.close(); # 3,源码 # import java.io.File; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.IntStream; public class DownloadFile { public static void main(String[] args) throws Exception { System.out.println("开始下载"); long start = System.currentTimeMillis(); // URL url = new URL("https://down.qq.com/qqweb/PCQQ/PCQQ_EXE/PCQQ2020.exe"); // HttpURLConnection conn = (HttpURLConnection)url.openConnection(); // int contentLength = conn.getContentLength(); File oriFile = new File("/Users/waynezhao/Downloads/日志/uat/community.2020-10-19.0.log"); long contentLength = oriFile.length(); final int THREAD_AMOUNT = 8;//开始8个线程进行下载 long threadLength = (contentLength + THREAD_AMOUNT - 1) / THREAD_AMOUNT;//获取每个线程需要下载的大小 //File file = new File("/Users/waynezhao/Downloads/PCQQ2020.exe"); File file = new File("/Users/waynezhao/Downloads/temp.log"); RandomAccessFile ref = new RandomAccessFile(file,"rws"); ref.setLength(contentLength);//设置下载之后的文件大小 ref.close(); ExecutorService executorService = Executors.newFixedThreadPool(THREAD_AMOUNT); CountDownLatch latch = new CountDownLatch(THREAD_AMOUNT); IntStream.range(0,THREAD_AMOUNT).forEach(i->{ executorService.submit(()->{ System.out.println("线程"+Thread.currentThread().getName()+"开始下载"); long threadStart = i * threadLength; long threadEnd = i * threadLength + threadLength - 1; System.out.println("线程"+Thread.currentThread().getName()+"下载范围:"+threadStart+"-"+threadEnd); try{ //HttpURLConnection connection = (HttpURLConnection)url.openConnection(); //connection.setRequestProperty("Range","bytes="+threadStart+"-"+threadEnd); //InputStream inputStream = connection.getInputStream(); RandomAccessFile oriRandomAccessFile = new RandomAccessFile(oriFile, "r"); oriRandomAccessFile.seek(threadStart); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rws"); randomAccessFile.seek(threadStart); byte[] buffer = new byte[1024]; int len; //while((len = inputStream.read(buffer)) != -1){ while((len = oriRandomAccessFile.read(buffer)) != -1){ randomAccessFile.write(buffer,0,len); } randomAccessFile.close(); oriRandomAccessFile.close(); }catch (Exception e){ e.printStackTrace(); } latch.countDown(); System.out.println("线程"+Thread.currentThread().getName()+"下载完成"); }); }); latch.await(); executorService.shutdown(); long end = System.currentTimeMillis(); System.out.println("完成下载,耗时:"+(end - start)); } }
还没有评论,来说两句吧...