`

多线程下载文件

 
阅读更多

网络蚂蚁、FlashGet、迅雷等支持HTTP协议的下载软件无一例外地使用了多线程下载技术。比起单线程下载,多线程下载在同一时间段内发出多个下载请求,每个下载请求负责下载一段内容,充分地利用了网络带宽。

当然多线程下载并非线程数越多越好。试想,一个极端 的情况:一个尺寸为1 024个字节的远程文件,动用1 024个线程来下载,每个线程平均只下载一个字节,创建线程的代价和对自身网络出口造成的堵塞远远大于分工下载带来的好处。因此,多线程下载存在一个权衡 的问题。一般来说,需要事先根据待下载的远程文件的尺寸来决定启用多少个线程,如果文件很小,则意味着使用单线程下载即可。而且,下载软件允许创建的线程 数一般是设置上限的,例如即使下载一个超大文件,也不能开启过多的线程,毕竟创建下载线程是需要耗费客户端资源的,并且线程之间存在着竞争网络带宽的关 系。总之,下载线程数往往是在待下载的远程文件尺寸、每个线程分担的字节数任务、线程数三者之间权衡的结果。

实战多线程下载,有几个技术难题有待攻克:

— 如何获取远程文件的尺寸,这关系到开启多少个下载线程。本节例程采用比较简单的线程数决策策略:固定每个线程分担的字节数任务,根据远程文件尺寸来决定需 要开启的下载线程,也就是不考虑下载线程数过多带来的负面影响。因此,获取远程文件的尺寸就成为了很关键的一个步骤。

— 如何实现分工下载,即每个线程只下载远程文件的一段。这是多线程HTTP下载的核心技术。

— 如何存储、组织各个线程下载得到的文件碎片,最后将其拼成一个完整的文件。

package com.yt.manager.net.download;

import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @Description:
 * @ClassName: DownFile
 * @Project: base-info
 * @Author: zxf
 * @Date: 2011-7-13
 */
public class DownFile {

	/**
	 * 下载
	 * 
	 * @throws Exception
	 * 
	 */
	public void down(String path, int threadnum) throws Exception {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(10 * 1000);
		conn.setRequestMethod("GET");
		// 获得网络文件的长度
		int length = conn.getContentLength();
		// 每个线程负责下载的文件大小
		int block = (length % threadnum) == 0 ? length / threadnum : length
				/ threadnum + 1;
		//从http相应消息获取的状态码,200:OK;401:Unauthorized
		if (conn.getResponseCode() == 200) {
			for (int i = 0; i < threadnum; i++) {
				// 开启线程下载
				new DownThread(i, new File(realPath(),getFileName(path)), block, url).start();
			}
		}
	}
	
	/**
	 * 文件的下载目录
	 * @return
	 */
	public String realPath(){
		String realPath = "h:/download";
		File file = new File(realPath);
		if (!file.exists()) {
			file.mkdirs();
		}
		return realPath;
	}

	/**
	 * 获取文件名
	 * @param path
	 * @return
	 */
	public String getFileName(String path) {
		return path.substring(path.lastIndexOf("/") + 1);
	}

	public static void main(String[] args) {
		DownFile test = new DownFile();
		//String path = "http://www.java.net/download/jdk6/6u10/promoted/b32/binaries/jdk-6u10-rc2-bin-b32-windows-i586-p-12_sep_2008.exe";
		String path ="http://www.baidu.com/img/baidu_sylogo1.gif";
		int threadnum = 3;
		try {
			test.down(path, threadnum);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 

package com.yt.manager.net.download;

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

/**
 * @Description:
 * @ClassName: DownThread
 * @Project: base-info
 * @Author: zxf
 * @Date: 2011-7-13
 */
public class DownThread extends Thread {
	private int id; // 线程id

	private File file;// 目标文件

	private int block;// 每个线程下载文件的大小

	private URL url;

	public DownThread() {
	}

	public DownThread(int id, File file, int block, URL url) {
		this.id = id;
		this.file = file;
		this.block = block;
		this.url = url;
	}

	@Override
	public void run() {
		int start = (id * block);// 当前线程开始下载处
		int end = (id + 1) * block - 1;// 当前线程结束下载处
		// 建立随机操作文件对象
		try {
			RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
			accessFile.seek(start);// 设置操作文件的入点
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5 * 1000);
			conn.setRequestMethod("GET");
			// 指定网络位置从什么位置开始下载,到什么位置结束
			conn.setRequestProperty("Range", "bytes=" + start + "-" + end + "");
			InputStream in = conn.getInputStream();// 获得输入流
			byte[] data = new byte[1024];
			int len = 0;
			while ((len = in.read(data)) != -1) {
				accessFile.write(data, 0, len);
			}
			accessFile.close();
			in.close();
			System.out.println("线程:" + id + "下载完成!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
 
分享到:
评论
1 楼 depravedangel 2011-11-25  
conn.setRequestProperty("Range", "bytes=" + start + "-" + end + "");
 

range需全部大写

相关推荐

    C#实现多线程下载文件

    通过上述步骤,我们可以实现一个高效的多线程文件下载器。这个过程涉及到的知识点包括:线程与线程池、异步编程、文件I/O、HTTP范围请求、异常处理和进度更新。这些知识对于任何希望深入理解C#并发编程和网络编程的...

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

    首先,多线程下载文件是一种提高下载速度的方法,通过将大文件分成多个小部分,每个部分由一个单独的线程负责下载,从而充分利用多核处理器的并行处理能力。在Java中,我们可以使用`java.util.concurrent`包中的`...

    android多线程下载文件

    在Android开发中,多线程下载文件是一种常见的优化策略,特别是在处理大文件或者网络环境不稳定的情况下,能够提高下载效率并减少资源浪费。本项目提供的就是一个实现了多线程断点续传功能的Android下载器,它包含...

    java实现多线程下载文件

    通过以上步骤,我们可以设计并实现一个高效的多线程文件下载系统。在实际项目中,还可以考虑使用成熟的库,如Apache HttpClient或OkHttp,它们提供了对多线程下载的良好支持。同时,结合Java的并发库,可以构建出更...

    Android多线程下载文件

    在Android应用开发中,多线程下载文件是一个常见的需求,特别是在处理大文件或者需要优化用户体验时。这个场景中,我们采用多线程技术来提高下载效率,并且支持断点续传功能,这意味着如果下载过程中因网络问题中断...

    可以多线程下载文件的c++客户端

    可以多线程下载文件c++的客户端软件,可以切割文件并传输

    C#多线程下载文件源码

    在C#编程中,多线程技术是一种提升应用程序性能的有效方式,特别是在处理耗时操作如文件下载时。本文将深入探讨如何使用C#实现多线程下载文件,并基于提供的源码进行分析和学习。 首先,多线程的概念是并发执行多个...

    C# 多线程下载文件

    在C#编程中,多线程技术是一种提升应用程序性能的有效方式,特别是在处理耗时操作如大文件下载时。本文将深入探讨如何利用C#实现多线程下载文件,并结合给出的"多线程下载文件"项目,理解其工作原理。 首先,让我们...

    多线程分别下载文件

    这个"多线程分别下载文件"的Demo是针对在ListView或GridView控件中实现的一项功能,允许用户选择多个文件进行并行下载,并且每个文件的下载进度可以在对应的列表项中实时更新,提供良好的用户体验。 首先,我们要...

    Android多线程下载文件实例

    在Android应用开发中,多线程技术是必不可少的,特别是在处理耗时操作,如网络请求、文件下载等场景。本文将深入探讨如何在Android中实现多线程下载文件的实例。 首先,我们要理解多线程的基本概念。在单线程环境中...

    qt多线程高效下载文件

    本项目"qt多线程高效下载文件"是基于Qt实现的一个实用工具,它利用多线程技术来提高文件下载的效率,特别是对于大文件或者需要同时下载多个文件的场景,这种多线程策略显得尤为重要。 在HTTP协议方面,它是互联网上...

    java多线程下载文件

    ### Java多线程断点下载文件:关键技术与实现 在当今高速互联网环境下,高效的数据传输技术变得至关重要。Java多线程断点续传文件下载技术就是一种能够显著提高下载速度和稳定性的方法。本文将深入解析Java多线程...

    关于vb多线程下载文件的例子

    下面我们将详细讲解如何使用VB创建一个简单的多线程文件下载程序。 首先,我们需要创建一个新的线程来执行下载任务。在VB中,我们可以创建一个`Thread`对象,并为其传递一个委托(Delegate),这个委托指向要在线程...

    delphi7多线程下载文件

    在Delphi7中,开发多线程下载文件的应用程序是一项技术含量较高的任务,涉及到并发处理、网络通信以及文件I/O等多个方面。在这个场景下,我们通常会利用Indy10库,尤其是其中的IdHTTP组件来实现网络请求,再结合多...

    htp多线程断点下载文件

    在IT领域,网络数据传输是不可或缺的一部分,而断点续传和多线程下载技术则大大提升了文件下载的效率和用户体验。"htp多线程断点下载文件"这一主题,涉及了网络编程、多线程技术和文件处理等多个知识点。 首先,...

    多线程实现文件下载,代码规范明了

    在多线程文件下载中,我们可以为每个线程创建一个Socket,分别与服务器保持连接,实现文件的分块下载。 2. HTTP:超文本传输协议是互联网上应用最广泛的一种网络协议。HTTP支持断点续传功能,非常适合大文件的下载...

    java多线程下载文件源码

    在Java编程中,多线程下载文件是一种优化大文件下载效率的技术。它通过将一个大文件分割成多个小部分,然后在不同的线程中并行下载这些部分,从而充分利用网络带宽,加快下载速度。本源码实现了这样一个功能,让下载...

    Python3中的单线程带进度条和多线程下载文件代码及注意事项

    写一个多线程分块下载文件工具。网上的一些代码可能会有些奇怪的问题,用的是类全局变量打开文件但在多线程中并未加锁,会导致文件有一定几率出现大小和源文件不同,即使文件大小相同,MD5值也不同,中间有一段是坏的...

    C# Winform 多线程下载

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

Global site tag (gtag.js) - Google Analytics