JAVA多线程下载网络文件

Wesley13
• 阅读 418

JAVA多线程下载网络文件,开启多个线程,同时下载网络文件。

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

/**  * 说明:  * 每一个线程下载的位置计算方式:  * 开始位置: (线程id - 1) * 每一块大小  * 结束位置: (线程id*每一块大小) - 1   *   * 注意:有时候不一定能够整除,所以最后一个线程的结束位置应该是文件的末尾  *    *  步骤:  *  1.本地创建一个大小跟服务器文件相同的临时文件  *  2.计算分配几个线程去下载服务器上的资源,知道每个线程下载文件的位置  *  3.开启三个线程,每一个线程下载对应位置的文件  *  4.如果所有的线程,都把自己的数据下载完毕后,服务器上的资源都被下载到本地了  *   * 作者: zhoubang   * 日期:2015年8月7日 上午11:20:06  */ public class MultiThreadDownload {     public static String path = "http://static.csdn.net/public/common/toolbar/css/index.css"; // 要下载的网络资源文件路径     public static int threadCount = 10; // 开启的线程数     public static int runningThread = 10; // 记录已经运行的线程数量     public static long startTime;

    private static final String filePath = "f:\\index.css"; //文件存放本地的路径

    /**      * 测试下载      *       * 作者: zhoubang       * 日期:2015年8月7日 上午11:16:23      * @param args      * @throws Exception      */     public static void main(String[] args) throws Exception {         startTime = System.currentTimeMillis();         // 1.连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件         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(filePath, "rwd");             // 指定创建的这个文件的长度             raf.setLength(length);             raf.close();             // 假设是3个线程去下载资源。             // 平均每一个线程下载的文件大小.             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.printf("服务器错误!");         }     }

    /**      * 下载文件的子线程,每一个线程下载对应位置的文件      *       * 作者: zhoubang       * 日期:2015年8月7日 上午11:16:34      */     public static class DownLoadThread extends Thread {         private int threadId;         private int startIndex;         private int endIndex;

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

        @Override         public void run() {             try {                 URL url = new URL(path);                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();                 conn.setConnectTimeout(5000);                 conn.setRequestMethod("GET");                 // 重要:请求服务器下载部分文件 指定文件的位置                 conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);                 // 从服务器请求全部资源返回200 ok如果从服务器请求部分资源 返回 206 ok                 int code = conn.getResponseCode();                 System.out.println("code:" + code);                 InputStream is = conn.getInputStream();// 已经设置了请求的位置,返回的是当前位置对应的文件的输入流                 RandomAccessFile raf = new RandomAccessFile(filePath, "rwd");                 // 随机写文件的时候从哪个位置开始写                 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 + "下载完毕");                 System.out.println((System.currentTimeMillis() - startTime));             } catch (Exception e) {                 e.printStackTrace();             } finally {                 runningThread--;                 if (runningThread == 0) {// 所有的线程执行完毕                     System.out.println("文件全部下载完毕!");                 }             }         }

    } }

     文章转载地址:http://www.cnblogs.com/zhoubang521/p/5200015.html

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这