`

多线程下载

阅读更多

           线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开起好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配。不难理解,如果你线程多的话,那下载的越快。现流行的下载软件都支持多线程。

           多线程下载案例:

 

           package com.test;

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

            /**

             * 下载线程类(定义下载从start到end的内容的线程)

             * 

             */


             class DownThread extends Thread {

 

                      // 定义字节数组(取水的竹筒)的长度
                      private final int BUFF_LEN = 32;
                      // 定义下载的起始点
                      private long start;
                      // 定义下载的结束点
                      private long end;
                      // 下载资源对应的输入流
                      private InputStream is;
                      // 将下载到的字节输出到raf中
                      private RandomAccessFile raf;

 

                      // 构造器,传入输入流,输出流和下载起始点、结束点
                      public DownThread(long start, long end, InputStream is, RandomAccessFile raf) {


                                 // 输出该线程负责下载的字节位置
                                 System.out.println(start + "---->" + end);
                                 this.start = start;
                                 this.end = end;
                                 this.is = is;
                                 this.raf = raf;
                      }

                      public void run() {


                                try {
                                        is.skip(start);
                                        raf.seek(start);


                                        // 定义读取输入流内容的的缓存数组(竹筒)
                                        byte[] buff = new byte[BUFF_LEN];


                                         // 本线程负责下载资源的大小
                                         long contentLen = end - start;


                                         // 定义最多需要读取几次就可以完成本线程的下载
                                          long times = contentLen / BUFF_LEN + 1;


                                         // 实际读取的字节数
                                          int hasRead = 0;


                                          for (int i = 0; i < times; i++) {


                                                     hasRead = is.read(buff);


                                                     // 如果读取的字节数小于0,则退出循环!
                                                     if (hasRead < 0) {
                                                            break;
                                                     }
                                                     raf.write(buff, 0, hasRead);
                                           }
                                   } catch (Exception ex) {
                                                ex.printStackTrace();
                                  }
                                   // 使用finally块来关闭当前线程的输入流、输出流
                                   finally {
                                              try {
                                                     if (is != null) {
                                                         is.close();
                                                     }
                                                     if (raf != null) {
                                                         raf.close();
                                                     }
                                              } catch (Exception ex) {
                                                          ex.printStackTrace();
                                    }
                              }
                         }
                  }

 

                  public class uploadResource {

 

                            public static void main(String[] args) {

 

                                      final int DOWN_THREAD_NUM = 6;
                                      final String OUT_FILE_NAME = "D:/******";
                                      InputStream[] isArr = new InputStream[DOWN_THREAD_NUM];
                                      RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];


                                      try {
                                            // 创建一个URL对象,例如
                                             URL url = new URL("http://images.china-pub.com/ebook35001-40000/35850/shupi.jpg");
                                           
                                            // 以此URL对象打开第一个输入流
                                            isArr[0] = url.openStream();
                                            long fileLen = getFileLength(url);
                                            System.out.println("网络资源的大小" + fileLen);


                                            // 以输出文件名创建第一个RandomAccessFile输出流
                                            outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw");


                                             // 创建一个与下载资源相同大小的空文件
                                             for (int i = 0; i < fileLen; i++) {
                                                    outArr[0].write(0);
                                            }
                                            // 每线程应该下载的字节数
                                            long numPerThred = fileLen / DOWN_THREAD_NUM;


                                            // 整个下载资源整除后剩下的余数
                                             long left = fileLen % DOWN_THREAD_NUM;
                                             for (int i = 0; i < DOWN_THREAD_NUM; i++) {


                                             // 为每个线程打开一个输入流、一个RandomAccessFile对象,
                                             // 让每个线程分别负责下载资源的不同部分。
                                                   if (i != 0) {
                                                                // 以URL打开多个输入流
                                                                 isArr[i] = url.openStream();


                                                                 // 以指定输出文件创建多个RandomAccessFile对象
                                                                 outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
                                                    }
                                                  // 分别启动多个线程来下载网络资源


                                                   if (i == DOWN_THREAD_NUM - 1) {


                                                   // 最后一个线程下载指定numPerThred+left个字节
                                                    new DownThread(i * numPerThred, (i + 1) * numPerThred+ left, isArr[i], outArr[i]).start();
                                                   } else {


                                                  // 每个线程负责下载一定的numPerThred个字节
                                                      new DownThread(i * numPerThred, (i + 1) * numPerThred,
                                                      isArr[i], outArr[i]).start();
                                                    }
                                               }
                                 } catch (Exception ex) {
                                              ex.printStackTrace();
                                 }
               }

                    定义获取指定网络资源的长度的方法


                    public static long getFileLength(URL url) throws Exception {


                               long length = 0;
                               // 打开该URL对应的URLConnection。
                              URLConnection con = url.openConnection();


                               // 获取连接URL资源的长度
                               long size = con.getContentLength();
                               length = size;


                               return length;
                      }
                  }

分享到:
评论

相关推荐

    C#实现支持断点续传多线程下载客户端工具类

    多线程下载则能显著提高大文件下载的速度,通过将文件分割成多个部分并同时下载来利用多核处理器的优势。 这个C# DIY HttpWebClient工具类基于对System.Net.WebClient的修改和扩展。WebClient是.NET Framework提供...

    易语言多线程下载不卡速度快

    在本项目中,“易语言多线程下载不卡速度快”是一个利用易语言实现的多线程下载工具,旨在提供高效、稳定的文件下载体验。通过多线程技术,该工具能够同时处理多个下载链接,使得下载过程更加流畅,减少因单一线程...

    C# Winform 多线程下载

    在C# Winform应用中实现多线程下载是一项常见的任务,尤其在处理大文件或需要提高下载速度的情况下。本文将详细讲解如何利用C#的多线程技术来创建一个Winform应用程序,实现高效的文件下载功能。 首先,我们需要...

    利用idhttp进行多线程下载

    在Delphi编程环境中,利用 Indy (Internet Direct) 的 `TIdHTTP` 组件进行多线程下载是一项常见的任务,尤其适用于处理大文件,以提高下载效率并提供更好的用户体验。`TIdHTTP` 是Indy库中的一个核心组件,用于执行...

    C#实现多线程下载文件

    本文将深入探讨如何在C#中实现多线程下载文件,涉及的知识点包括线程池、异步编程、进度更新以及错误处理。 首先,我们需要了解线程的基本概念。在C#中,线程是程序执行的独立路径,每个线程都有自己的调用堆栈,...

    多线程下载器.zip易语言项目例子源码下载

    《多线程下载器——易语言项目实例解析》 在当今高速发展的互联网世界中,高效的数据传输成为了一项重要的需求。多线程下载器作为提升下载速度的有效工具,被广泛应用于各种场景。本文将深入剖析一个基于易语言实现...

    多线程下载+进度条

    在IT领域,多线程下载和进度条显示是提高用户体验和优化下载效率的重要技术。这里我们将深入探讨这两个概念以及如何实现它们。 首先,多线程下载是指在一个下载任务中使用多个独立的线程同时从服务器获取数据。这种...

    C# httpwebrequest 多线程下载类

    在多线程下载场景中,我们通常会为每个下载任务创建一个独立的线程,以便并发执行多个请求,提高下载效率。 下面,我们将逐步解析实现`C# httpwebrequest 多线程下载类`的关键步骤: 1. **创建下载类**:首先,...

    SpringBoot版本的多线程下载文件,分段下载文件

    本篇将深入探讨如何利用SpringBoot实现多线程下载文件以及分段下载文件的技术。 首先,多线程下载文件是一种提高下载速度的方法,通过将大文件分成多个小部分,每个部分由一个单独的线程负责下载,从而充分利用多核...

    基于Qt5和libcurl的多线程下载器.zip

    【标题】基于Qt5和libcurl的多线程下载器是一种高效的C++应用程序,它利用了Qt5的图形用户界面(GUI)库和libcurl库的功能来实现文件的多线程下载。Qt5是一个功能丰富的跨平台应用开发框架,支持Windows、Linux、...

    多线程下载工具

    标题中的“多线程下载工具”指的是一个利用多线程技术来提高文件下载速度的应用程序。在计算机编程中,多线程是指在一个程序内同时执行多个独立的线程,每个线程负责不同的任务,比如在下载场景中,一个线程负责处理...

    多线程下载原理

    在IT领域,多线程下载是一项重要的技术,尤其在处理大文件或大量数据时,能够显著提高下载效率。本文将详细解析"多线程下载原理",并结合提供的java工程net和android工程videonews来深入理解这一概念。 首先,我们...

    易语言多线程下载源码

    在“易语言多线程下载源码”这个主题中,我们将深入探讨如何使用易语言实现高效的多线程下载功能。 在互联网上下载大文件时,单线程下载往往速度受限,而多线程下载可以显著提高下载效率,因为它允许同时从服务器...

    android断点续传_多线程下载demo

    在Android开发中,断点续传和多线程下载是提高用户下载体验的重要技术。本文将深入探讨如何在Android客户端实现这些功能,并结合服务器端的配合来完成整个流程。 首先,断点续传(Resumable Download)允许用户在...

    python m3u8多线程下载器

    在本项目中,我们关注的是利用Python实现的“m3u8多线程下载器”。M3U8是一种基于HTTP/HTTPS协议的流媒体格式,常用于在线视频播放,尤其在移动设备上。它将视频文件分割成多个小片段,方便流式传输。 这个下载器...

    多线程下载demo

    在IT领域,多线程下载是一种常见的优化网络资源获取的技术,尤其在大文件下载时能够显著提高下载速度。本文将详细解析多线程下载的原理、实现方式以及断点续传的概念。 首先,多线程下载的核心思想是将一个大的文件...

    Java多线程下载器

    Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个部分并同时下载,显著提高了下载速度。在Java中实现多线程下载器涉及许多关键概念和技术,包括线程、并发控制、网络I/O...

    (Java)FTP多线程下载源代码

    采用apache commons开发包,实现了FTP多线程下载,并有简单的包括进度条的界面,代码的运行:1 把自己的PC配置成FTP服务器(只需下载Serc-U软件)2 建立用户,用户名:zhangyu,密码:123,设置根目录,并拷贝进一些...

Global site tag (gtag.js) - Google Analytics