当前位置: 首页 > news >正文

多线程下载(转)

原文是在52上下载的。

感觉我们对IO和URL这些不够熟悉.很简单的.之前自己尝试过,感觉复杂化了,但也不好说.其实最想要的还是类似idm这种多线程,呵呵.

代码:

package com.test_four;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class Demo {
    public static int threadCount = 3;
    public static void main(String[] args) throws Exception {
//   1.连接服务器,获取一个文件,获取一个文件,获取文件的长度,在本地创建一个大小和服务器文件一样大的临时文件
        String path = "https://admdownload.adobe.com/bin/livebeta/flashplayer24_va_install.exe";
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        int code = conn.getResponseCode();
        if (code == 200) {
            //服务器返回的数据的长度 实际上就是文件的长度
            int length = conn.getContentLength();
            System.out.println("文件总长度:" + length);
//            在客户端本地创建出来一个大小跟服务器端文件一样的临时文件
            RandomAccessFile raf = new RandomAccessFile("xxx.exe", "rw");
//          指定创建的这个文件的长度
            raf.setLength(length);
            raf.close();
//           假设是三个线程去下载资源
//       平均每一个线程下载的文件的大小
            int blockSize = length/threadCount;
            for(int threadId = 1;threadId<=threadCount;threadId++){
//                第一个线程下载的开始位置
                int startIndex = (threadId -1)*blockSize;
                int endIndex = threadId*blockSize -1;
                if (threadId == threadCount) {//最后一个线程下载的长度要稍微长一点
                    endIndex = length;
                }
                System.out.println("线程:"+ threadId +"下载:---"+ startIndex +"--->"+ endIndex);
                new DownloadThread(path, threadId, startIndex, endIndex).start();
            }
        } else {
            System.out.println("服务器错误");
        }

    }
    public static class DownloadThread extends Thread{
        private int threadId;
        private int startIndex;
        private int endIndex;
        private String path;
        @Override
        public void run() {
            try {
                URL url = new URL(path);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(5000);
                connection.setRequestMethod("GET");
//                重要:请求服务器下载部分的文件指定文件的位置
                connection.setRequestProperty("Range","bytes=" + startIndex +"-" +endIndex);
                int code = connection.getResponseCode();//从服务器请求全部资源200 ok   如果从服务器请求部分资源206 ok
//                System.out.println("code:" + code);
                InputStream is =connection.getInputStream();//已经设置了请求的位置,返回的是当前位置对应的文件的输入流
                RandomAccessFile raf = new RandomAccessFile("xxx.exe", "rw");
                raf.seek(startIndex);//随机写文件的时候从哪个位置开始写

                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = is.read(buffer))!=-1) {
                    raf.write(buffer, 0, len);
                }
                is.close();
                raf.close();
                System.out.println("线程:"+threadId +"下载完毕");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /*
         * threadId 线程id
         * startIndex 线程下载的开始位置
         * endIndex 线程下载的结束位置
         * path 下载文件在服务器的路径
         */
        public DownloadThread(String path,int threadId, int startIndex, int endIndex) {
            super();
            this.threadId = threadId;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.path = path;
        }
    }

}

 

相关文章:

  • 开源加密解密库比较
  • 某道Pwn(格式化字符串漏洞)
  • 深入分析java web技术内幕----读书笔记(六)
  • 阻塞、非阻塞、同步、异步浅析
  • JqERY
  • BZOJ 4756 线段树合并(线段树)
  • 给自定义tabBar的按钮添加点击放大缩小的动画
  • idea 实现热部署
  • Advanced Auto Layout:Working with Self-Sizing Table View Cells
  • 震精 - PostgreSQL 单机3.9 万亿/天(计数器、序列、自增)
  • 什么是 SHTML
  • mysql57修改root密码
  • python3编码问题终结者--还搞不懂你来找我
  • Python(三)之Python的表达式和语句概述
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • 深入了解以太坊
  • [数据结构]链表的实现在PHP中
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • CEF与代理
  • Iterator 和 for...of 循环
  • JDK 6和JDK 7中的substring()方法
  • SQLServer之创建显式事务
  • 聚类分析——Kmeans
  • 前端
  • 试着探索高并发下的系统架构面貌
  • 自制字幕遮挡器
  • 白色的风信子
  • AI算硅基生命吗,为什么?
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​如何防止网络攻击?
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #pragma预处理命令
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (剑指Offer)面试题34:丑数
  • (蓝桥杯每日一题)love
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)Oracle存储过程编写经验和优化措施
  • (转)甲方乙方——赵民谈找工作
  • (转)我也是一只IT小小鸟
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .dwp和.webpart的区别
  • .java 9 找不到符号_java找不到符号
  • .net CHARTING图表控件下载地址
  • .NET Core引入性能分析引导优化
  • .NET MVC之AOP
  • .net 托管代码与非托管代码
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .net6+aspose.words导出word并转pdf
  • .NET程序员迈向卓越的必由之路
  • .NET命名规范和开发约定