`
aokunsang
  • 浏览: 815279 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

多线程分段下载文件

    博客分类:
  • Java
阅读更多

 

断点续传的原理:

把一个文件分为n个小文件,程序分n个线程去下载每一个小文件。阅读有关资料,IE浏览器传递给服务端的时候可以传递一个请求信息"Range":如:RANGE: bytes=2000070-  一看就知道告诉服务器下载的时候从2000070字节开始下载。值得注意的是response.getResponseCode()为206,不再是200了。

 

上代码:

 

/**
 * 下载工具类
 * 
 * @author aokunsang
 * 
 */
public class FileDownloader {

	private HttpURLConnection conn;

	public static void main(String[] args) throws Exception {
		FileDownloader load = new FileDownloader();
		load.download();
	}
	
	/**
	 * 开始下载
	 */
	public void download() throws Exception {
		HttpConnect connect = new HttpConnect(1);
		int fileSize = 0, threadSize = 3; // 文件长度和线程数
		conn = connect.initConnction();
		conn.connect();
		if (conn.getResponseCode() == 200) {
			fileSize = conn.getContentLength();
			conn.disconnect();
		}
		int perthThreadSize = fileSize / 3 + 1;   //每个线程需要下载的文件大小
		RandomAccessFile raf = new RandomAccessFile(new File("D://ca.mp3"), "rw");
		raf.setLength(fileSize);
		raf.close();
		long startTime = System.currentTimeMillis();
		for (int i = 0; i < threadSize; i++) {
			int startpos = i * perthThreadSize;  //线程开始下载的位置
			RandomAccessFile raff = new RandomAccessFile(new File("D://ca.mp3"), "rw");
			raff.seek(startpos);
			new myThread(startpos, perthThreadSize, i, raff).start();
		}
		long endTime = System.currentTimeMillis();
		
		while(Thread.activeCount()>1){}  //防止main线程结束而导致下载线程被销毁
		System.out.println("--------------下载完成,共耗时:"+(endTime-startTime)/(60*1000)+"分钟--------");
	}

	class myThread extends Thread {
		private int startpos;
		private int perThreadSize;
		private int threadId;
		private RandomAccessFile raf;

		public myThread(int startpos, int perThreadSize, int threadId,
				RandomAccessFile raf) {
			this.startpos = startpos;
			this.perThreadSize = perThreadSize;
			this.threadId = threadId;
			this.raf = raf;
		}

		@Override
		public void run() {
			HttpConnect connect = new HttpConnect(0);
			HttpURLConnection con = connect.initConnction();
			con.setRequestProperty("Range", "bytes=" + this.startpos + "-");
			try {
				InputStream is = con.getInputStream();
				byte[] bt = new byte[1024];
				int length = 0;
				int len = 0;
				while (length < this.perThreadSize && (len = is.read(bt)) != -1) {
					raf.write(bt, 0, len);
					length += len;
				}
				raf.close();
				is.close();
				System.out.println("线程"+threadId+"完成!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	class HttpConnect {
		private int flag;

		public HttpConnect(int flag) {
			this.flag = flag;
		}

		public HttpURLConnection initConnction() {
			HttpURLConnection connection = null;
			try {
				URL url = new URL(HttpConnectParams.URLSTRING.content);
				connection = (HttpURLConnection) url.openConnection();
				connection.setConnectTimeout(Integer
						.parseInt(HttpConnectParams.CONNECTTIEMEDOUT.content));
				connection.setRequestMethod(HttpConnectParams.POST.content);
				connection.setRequestProperty(HttpConnectParams.ACCECT.header,
						HttpConnectParams.ACCECT.content);
				connection.setRequestProperty(
						HttpConnectParams.ACCECT_LANGAGE.header,
						HttpConnectParams.ACCECT_LANGAGE.content);
				connection.setRequestProperty(HttpConnectParams.CHARSET.header,
						HttpConnectParams.CHARSET.content);
				if (flag == 1) {
					connection.setRequestProperty(
							HttpConnectParams.KEEPCONNECT.header,
							HttpConnectParams.KEEPCONNECT.content);
				}
			} catch (Exception e) {
				connection = null;
			}
			return connection;
		}
	}
}

 

/**

 * HTTP请求的一些常量信息
 * @author aokunsang
 *
 */
public enum HttpConnectParams {
	/**
	 * URL地址(mp3格式的音乐文件)
	 */
	URLSTRING("http://www.61mp3.cn/music/%B6%F9%CD%AF%B8%E8%C7%FA/%CA%AE%B6%FE%C9%FA%D0%A4%B8%E8.mp3"),
	/**
	 * 请求的方式
	 */
	POST("GET"),
	/**
	 *  请求的格式
	 */
	ACCECT("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"),
	/**
	 * 请求的语言
	 */
	ACCECT_LANGAGE("Accept-Language","zh-CN"),
	/**
	 * 请求的字符集编码
	 */
	CHARSET("Charset","UTF-8"),
	/**
	 * 链接的超时数
	 */
	CONNECTTIEMEDOUT("5000"),
	/**
	 * 保持链接
	 */
	KEEPCONNECT("Connection","Keep-Alive");
	
	public String header; //标题
	public String content; //内容
	
	private HttpConnectParams(String header,String content) {
		this.header = header;
		this.content = content;
	}
	private HttpConnectParams(String content){
		this.content = content;
	}
}

 

 

分享到:
评论

相关推荐

    Android多线程分段下载源码

    在Android开发中,多线程分段下载是一项重要的技术,特别是在处理大文件或者网络环境不稳定的情况下,能够提高下载效率并优化用户体验。这个"Android多线程分段下载源码"实例是一个很好的学习资源,它实现了文件的...

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

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

    httpclient多线程下载(分段下载)实践

    在大型文件下载时,为了提高效率和用户体验,通常会采用多线程分段下载的方式。本篇文章将深入探讨如何使用HTTPClient进行多线程分段下载的实践。 首先,我们要理解多线程下载的基本原理。多线程下载是通过将大文件...

    socke多线程多服务器分段下载文件

    本文将深入探讨如何使用`socket`实现多线程多服务器分段下载文件的技术细节,这是一项旨在提高文件下载速度并支持断点续传的重要技术。 首先,我们要理解`socket`的基本概念。`socket`是网络通信中的一个接口,它...

    纯JavaFX实现的多线程分段下载工具源码

    该源码项目是一个基于JavaFX的多线程分段下载工具,完全由Java语言编写,不依赖任何第三方库,提供了一种高效且直观的下载方式。以下是对该项目中涉及的关键技术点的详细解释: 1. **JavaFX**: JavaFX是Oracle...

    多线程分别下载文件

    在Android开发中,多线程技术常常用于提升应用程序的性能,特别是在处理耗时操作,如文件下载时。这个"多线程分别下载文件"的Demo是针对在ListView或GridView控件中实现的一项功能,允许用户选择多个文件进行并行...

    FTP多线程上传下载、断点续传、分段下载--田景吉之C#版本

    总的来说,FTP多线程上传下载、断点续传和分段下载是提升FTP操作性能的重要技术,它们在大文件传输场景中尤其有用。C#提供的强大并发支持和丰富的第三方库使得实现这些功能变得更加便捷。在实际应用中,开发者需要...

    java分段文件下载的实现与多线程下载最新版

    在Java编程中,分段文件下载和多线程下载是提高大文件下载效率的重要技术。以下将详细解释这两种技术的实现及其在项目中的应用。 **分段文件下载**: 分段文件下载是一种将大文件分割成多个小部分,然后分别下载的...

    JAVA代码实现多线程分段下载+断点续传

    JAVA代码实现多线程分段下载+断点续传 原理很清楚,但是其中涉及到几个关键的问题: 1.需要请求的数据如何分段。 2.分段下载的数据如何组装成完整的数据文件。 3.断点的数据如何保存,再次下载如何继续上次保存的...

    使用RandomAccessFie分段写大文件,创建多线程程席、通讨多线程分段读取大文件并分段写入到新文件

    本教程将重点讲解如何使用`RandomAccessFile`类进行大文件的分段读写,并通过多线程技术提高效率,实现大文件的高效处理。 首先,让我们了解`RandomAccessFile`。它是Java I/O库中的一个类,允许对文件进行随机访问...

    HTTP分段下载/断点续传/多线程下载

    代码作用:多线程分段下载,加快下载速度,加入适当代码可支持断点下载 ================================================= ·示例代码位置: [项目目录]/src-app/app/DownloaderApp.java 代码里写了注释,有一定...

    分段下载文件提升下载速度

    想要下载国外的一些视频速度太慢所以自己写了一个工具,利用多线程分段下载单个资源,并且使用5秒的TimeOut以及二十次的重试次数达到高速下载的目的,实测有效,下载某MMD网站的资源速度从20kb/s提升到了300kb/s,...

    Delphi线程池实现多线程FTP分段下载组件

    Delphi线程池实现多线程FTP分段下载组件 by :renshouren mail:114032666@qq.com QQ:114032666 2019.10.05 使用的组件 1、TIdFTP Indy FTP客户端 2、TThreadsPool 线程池 工作原理及流程 调用本单元,将自动在程序...

    java实现多线程下载

    在Java编程中,多线程下载是一种常见的优化技术,它通过将大文件分割成多个小块,然后在不同的线程中并行下载这些块来提高下载速度。这种技术尤其适用于网络带宽有限或者文件体积较大的情况。下面我们将深入探讨如何...

    断点续传和多线程下载,可实现大文件传输

    断点续传和多线程下载是两种在网络编程中用于优化大文件传输的技术,尤其在C++、C++Builder和VC等环境下应用广泛。在Windows系统中,它们可以帮助提高文件下载速度,降低网络资源的浪费,并能处理网络中断后的恢复...

    Java 利用多线程实现文件的分片下载

    刚学完多线程和线程池,以及线程爱好者。 使用场景及目标: 大文件的快速下载,经测试在100M带宽的网络下,下载一个40M的文件,不超过两秒钟,当然还得根据自己电脑的配置来讲。 其他说明: 文件如果特别小,而...

    单、多线程断点续传下载

    总结起来,单、多线程断点续传下载是Android应用中重要的文件下载技术,它涉及到网络编程、多线程并发和文件操作等多个方面。理解并熟练掌握这一技术,对于提升用户体验和优化应用性能至关重要。

    多线程读取大文件

    在文件传输中,可以多线程下载大文件,提高下载速率。 总结来说,多线程读取大文件是提升系统性能的有效手段,它结合了并行处理和I/O操作优化,减少了整体处理时间。开发者应根据具体的应用场景和语言特性,选择...

    java使用多线程读取超大文件

    Java使用多线程读取超大文件 Java使用多线程读取超大文件是指在java语言中使用多线程技术来读取超大文件,以提高读取速度和效率。下面是该技术的详细介绍和实现方法。 多线程读取超大文件的必要性 在读取超大文件...

    c# 多线程断点续传文件传输程序

    在C#编程中,开发一个支持多线程和断点续传功能的文件传输程序是一项技术挑战,但也是非常实用的技能。这样的程序可以显著提高大文件传输的效率和可靠性,尤其是在网络不稳定的情况下。以下是关于这个主题的一些关键...

Global site tag (gtag.js) - Google Analytics