当前位置:首页 > Java技术 > Java多线程下载文件实例

Java多线程下载文件实例

2022年08月05日 22:03:38Java技术4
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class FileDownLoadTest {
    
    
     private static final int TCOUNT = 10;
    
     private CountDownLatch latch = new CountDownLatch(TCOUNT);

     private long completeLength = 0;
    
     private long fileLength;
     /**
     * @param args
     * @throws Exception
     */
     public static void main(String[] args) throws Exception {
         
          long begin = System.currentTimeMillis();
          new FileDownLoadTest().download("http://test1.com");
          System.out.println(System.currentTimeMillis() - begin);
     }
    
    
     public void download(String address) throws Exception{
          ExecutorService service = Executors.newFixedThreadPool(TCOUNT);
          URL url = new URL(address);
          URLConnection cn = url.openConnection();
          cn.setRequestProperty("Referer", "http://www.test.com");
          fileLength = cn.getContentLength();
          long packageLength = fileLength/TCOUNT;
          long leftLength = fileLength%TCOUNT;
          RandomAccessFile file = new RandomAccessFile("test.rar","rw");
          //计算每个线程请求文件的开始和结束位置
          long pos = 0;
          long endPos = pos + packageLength;
          for(int i=0; i<TCOUNT; i++){
               if(leftLength >0){
                    endPos ++;
                    leftLength--;
               }
               service.execute(new DownLoadThread(url, file, pos, endPos));
               pos = endPos;
          }
          latch.await();
     }
    
     class DownLoadThread implements Runnable{
         
          private URL url;
          private RandomAccessFile file;
          private long from;
          private long end;
         
          DownLoadThread(URL url, RandomAccessFile file, long from, long end){
               this.url = url;
               this.file = file;
               this.from = from;
               this.end = end;
          }
         
         
          public void run() {
               long pos = from;
               byte[] buf = new byte[512];
               try {
                    HttpURLConnection cn = (HttpURLConnection) url.openConnection();
                    cn.setRequestProperty("Range", "bytes=" + from + "-" + end);
                    if(cn.getResponseCode() != 200 && cn.getResponseCode()!=206){
                         run();
                         return;
                    }
                    BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());
                    int len ;
                    while((len = bis.read(buf)) != -1){
                         synchronized(file){
                              file.seek(pos);
                              file.write(buf, 0, len);
                         }
                         pos += len;
                         completeLength +=len;
                         System.out.println(completeLength * 100 /fileLength + "%");
                    }
                    cn.disconnect();
                    latch.countDown();
               } catch (IOException e) {
                    e.printStackTrace();
                   
               }
          }
     }
}

 

作者:江上一叶舟
来源链接:https://blog.csdn.net/laladebon/article/details/82351408

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/17935.html

分享给朋友:

“Java多线程下载文件实例” 的相关文章

两年前写的Java基础总结书

两年前写的Java基础总结书

想法衍生 两年前的我,突发奇想,把自己学的Java基础进行规范化的整理,因为自己的文档编辑能力有限,所以写的排版不是很好,参照图书排版的形式,将书籍进行整理,可以供学习Java基础的朋友参考,由于时间有限,可能也会有问题,请指出。下载地址在最后 截图如下:...

Java中四种访问修饰符的区别

在java中共有4种访问级别,按访问权限由高到低为:public(公有的)、protected(受保护的)、友好的(没有任何访问权限关键字修饰)和private(私有的)。 类型 类内部 同一个包其...

深入理解 Java 并发锁

深入理解 Java 并发锁

📦 本文以及示例源码已归档在 javacore 一、并发锁简介 确保线程安全最常见的做法是利用锁机制(Lock、sychronized)来对共享数据做互斥同步,这样在同一个时刻,只有一个线程可以执行某个方法或者某个代码块,那么操作必然是原子性的,线程安全的...

全面了解 Java 原子变量类

📦 本文以及示例源码已归档在 javacore 一、原子变量类简介 为何需要原子变量类 保证线程安全是 Java 并发编程必须要解决的重要问题。Java 从原子性、可见性、有序性这三大特性入手,确保多线程的数据一致性。 确保线程安全最...

Java 并发核心机制

Java 并发核心机制

📦 本文以及示例源码已归档在 javacore 一、J.U.C 简介 Java 的 java.util.concurrent 包(简称 J.U.C)中提供了大量并发工具类,是 Java 并发能力的主要体现(注意,不是全部,有部分并发能力的支持在其他包中)。...

Java 内存模型

Java 内存模型

📦 本文以及示例源码已归档在 javacore Java 内存模型(Java Memory Model),简称 JMM。 JVM 中试图定义一种 JMM 来屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。...

冒泡排序的原理,思路,以及算法分析(Java实现)

冒泡排序的原理,思路,以及算法分析(Java实现)

冒泡排序 如果遇到相等的值不进行交换,那这种排序方式是稳定的排序方式。 1.原理:比较两个相邻的元素,将值大的元素交换到右边 2.思路:依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面。 (1)第一次比较:首先比较第...

Java实现阶乘运算

n!=123*…n 学习编程就是要了解从问题到程序是如何实现的 Scanner in=new Scanner(System.in); int n ; n=in.nextInt(); // int i=1; int factor=1;...

java之整数的分解可以理解为倒序输出

Scanner in=new Scanner(System.in); int number ; number=in.nextInt(); int result=0; do{ int diget=number%10;...

java比较语句常犯错误和三个数比较大小

1.忘了大括号 解决: 任何if else语句后面加大括号,哪怕只有一句 2.忘了分号 if后面不能有分号 3.代码分格 Scanner in=new Scanner(System.in); int x; int y; int z;...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。