`
lvwenwen
  • 浏览: 955380 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

java多线程断点续传

阅读更多

 在android下面的断点续传和java下面没有太大的冲突,就是在配置文件里面加上一些特定的访问权限就可以了
如下式在AndroidManifest.xml加入的权限
 
<!--  访问internet权限 -->
       <uses-permission android:name="android.permission.INTERNET" />
       <!--  在SDCard中创建与删除文件权限-->
       <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
       <!--  往SDCard写入数据权限-->
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这个准备工作做好了就可以直接编码了
第一步创建multiThreaddownload.java
 
package com.cn.download;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
 
import com.cn.coocaa.download.FileDownloadThread;
 
public class MultiThreadDownload extends Thread {
        //定义的一些常量变量,看名字就知道什么意思了
	private static final int BUFFER_SIZE = 1024;
	private int blockSize;
	private int threadNum = 5;
	private int fileSize;
	private int downloadedSize;
	String urlStr, threadNo, fileName;
	private String savePath;
	private int downloadPercent = 0 , downloadSpeed = 0, usedTime=0;
	private long startTime,curTime;
	private	boolean completed = false;
        //用URL,保存路径,保存名称来构造。
	public MultiThreadDownload(String URL, String savePath, String fileName) {
		this.urlStr = URL;
		this.savePath = savePath;
		this.fileName = fileName;
	}
 
	@Override
	public void run() {
		FileDownloadThread[] fds = new FileDownloadThread[threadNum];
		try {
			URL url = new URL(urlStr);
			URLConnection conn = url.openConnection();
			fileSize = conn.getContentLength();
			blockSize = fileSize / threadNum;
			File file[] = new File[threadNum];
                        //根据默认的线程数,或者自己修改设置的线程数来分块,创建分块后的文件块
			for (int i = 0; i < threadNum; i++) {
				file[i] = new File(savePath + fileName + ".part"
						+ String.valueOf(i));
                                //将分块的文件交给每个线程处理,最后一块应该大于等于平均块,因为可能有余数
				FileDownloadThread fdt = new FileDownloadThread(url, file[i], i
						* blockSize, (i + 1) != threadNum ? ((i + 1)
						* blockSize - 1) : fileSize);
				fdt.setName("Thread" + i);
				fdt.start();
				fds[i] = fdt;
			}
			startTime = System.currentTimeMillis();
                        //获取起始下载的时间,用次来计算速度。
			boolean finished = false;
			while (!finished) {
				downloadedSize = 0;
				finished = true;
				for (int i = 0; i < fds.length; i++) {
					downloadedSize += fds[i].getDownloadSize();
					if (!fds[i].isFinished()) {
						finished = false;
					}
				}
                                //计算下载的百分比
				downloadPercent = (downloadedSize*100)/fileSize;
                                //获取当前时间,计算平均下载速度
				curTime = System.currentTimeMillis();
				usedTime =(int)((curTime-startTime)/1000);
				if(usedTime==0)
					usedTime =1;
				downloadSpeed = (downloadedSize/usedTime)/1024;
				sleep(1000);
			}
                       //这个是分块下载完成的标志
			completed = true;
                        //进行模块整合
			RandomAccessFile raf = new RandomAccessFile(savePath + fileName,
					"rw");
			byte[] tempbytes = new byte[BUFFER_SIZE];
			InputStream in = null;
			int byteread = 0;
			for (int i = 0; i < threadNum; i++) {
				in = new FileInputStream(file[i]);
				while ((byteread = in.read(tempbytes)) != -1)
				{
					raf.write(tempbytes, 0, byteread);
				}
                                //每次整合完一块就删除一块。
				in.close();
				file[i].delete();
			}
			raf.close();
 
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
       //获取下载百分比
	public int getDownloadPercent(){
		return this.downloadPercent;
	}
       //获取下载速度
	public int getDownloadSpeed(){
		return this.downloadSpeed;
	}
       //修改默认线程数
	public void setThreadNum(int threadNum){
		this.threadNum = threadNum;
	}
        //分块下载完成的标志
	public boolean isCompleted(){
		return this.completed;
	}
}
第二步 创建filedownloadthread.java
package com.cn.download;
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
 
public class FileDownloadThread extends Thread {
	private static final int BUFFER_SIZE = 1024;
	private URL url;
	private File file;
	private int startPosition;
	private int endPosition;
	private int curPosition;
	private boolean finished = false;
	private int downloadSize = 0;
       //分块构造函数
	public FileDownloadThread(URL url, File file, int startPosition,
			int endPosition) {
		this.url = url;
		this.file = file;
		this.startPosition = startPosition;
		this.curPosition = startPosition;
		this.endPosition = endPosition;
	}
 
	public void run() {
 
 
		BufferedInputStream bis = null;
		RandomAccessFile fos = null;
		byte[] buf = new byte[BUFFER_SIZE];
		URLConnection con = null;
		try {
                       //打开URL连接
			con = url.openConnection();
			con.setAllowUserInteraction(true);
                       //判断是否该文件存在,如果存在且下载完成,直接返回。
			if ((file.length() + startPosition) == endPosition) {
				this.finished = true;
			}
                        //文件未下载完成,获取到当前指针位置,继续下载。
                         else {
				con.setRequestProperty("Range", "bytes="
						+ (startPosition + file.length()) + "-" + endPosition);
				fos = new RandomAccessFile(file, "rw");
				fos.seek(file.length());
				bis = new BufferedInputStream(con.getInputStream());
				while (curPosition < endPosition) {
					int len = bis.read(buf, 0, BUFFER_SIZE);
					if (len == -1) {
						break;
					}
					fos.write(buf, 0, len);
					curPosition = curPosition + len;
					if (curPosition > endPosition) {
						downloadSize += len - (curPosition - endPosition) + 1;
					} else {
						downloadSize += len;
					}
				}
				this.finished = true;
				bis.close();
				fos.close();
			}
		} catch (IOException e) {
			System.out.println(getName() + " Error:" + e.getMessage());
		}
	}
 
	public boolean isFinished() {
		return finished;
	}
 
	public int getDownloadSize() {
		return downloadSize;
	}
}
上述两个文件就完成了多线程断点续传。
 
 
 
无需使用任何配置文件或者数据库,就可以接上次的断点进行续传操作。
 
原理流程:
         1、获取文件大小
         2、将文件按照所设定的线程数进行分块请求。
         3、检查是否存在断点情况,如果有断点情况则进行断点查找,然后再请求。
         4、分块下载。
         5、下载完成后文件整合,将分块文件删除掉。
         6、好了,你需要下载的文件就可以完成了。
 
 
总之了,在这里也是一种实现无需配置文件的方式吧,我提供的只是一个外部调用包,所以这个配置文件或者数据库记录的东西有很大的局限性,所以就切割了,
 
如果有什么更好的想法,希望能相互交流交流。
 
转载请注明:http://alloxa.blog.51cto.com/
 
 
 
分享到:
评论

相关推荐

    java多线程断点续传下载

    Java多线程断点续传下载是一个复杂但实用的技术,尤其在处理大文件或网络不稳定时,能够提高用户体验并优化资源利用。以下是对这个主题的详细解析: **1. Java多线程** Java多线程是指在一个Java应用程序中同时执行...

    java 多线程断点续传

    下面将详细探讨如何在Java中实现多线程断点续传。 首先,我们需要理解多线程的概念。在Java中,我们可以使用`Thread`类或`Runnable`接口来创建线程。当一个线程被创建后,它可以与主线程并行运行,每个线程都有自己...

    java多线程断点续传[借鉴].pdf

    总结来说,Java实现的多线程断点续传涉及的技术点包括: 1. 并发编程:使用`ExecutorService`、`CountDownLatch`进行线程管理和同步。 2. 文件操作:分析和合并临时文件,实现断点续传。 3. 网络I/O:通过`...

    JAVA多线程断点续传下载程序

    Java多线程断点续传下载程序是一种高级的软件实现技术,它结合了Java的并发处理能力和文件传输的策略,以提高下载效率和用户体验。在这个项目中,我们主要关注两个核心概念:多线程和断点续传。 首先,多线程是Java...

    java断点续传,刚刚整理出来多线程处理

    然而,实现多线程断点续传需要解决几个问题: 1. **同步管理**:多个线程可能会同时访问同一个文件的部分,因此需要使用`synchronized`关键字或`Lock`对象来确保并发安全。 2. **断点信息共享**:每个线程需要知道...

    java多线程断点续传.pdf

    Java多线程断点续传是一种在网络编程中经常使用的文件下载技术。当网络下载过程中遇到意外情况,比如网络断开、用户退出,或者程序异常退出时,能够从上次中断的位置继续下载,而不是重新开始。利用Java多线程技术,...

    java实现多线程断点续传下载

    通过以上步骤,我们可以构建一个功能完备的Java多线程断点续传下载程序。这个项目不仅可以帮助初学者理解多线程和网络编程的基本概念,也可以作为实际项目开发中的一个参考模板。对于想要深入研究Java网络编程和并发...

    java ftp 多线程 断点续传等知识

    而"多线程"和"断点"这两个文件名可能是指相关示例代码或文档,可以进一步帮助你理解和实践Java FTP的多线程下载和断点续传。 在实际应用中,还需要考虑其他因素,如错误处理、网络状况的监控、文件完整性检查等。...

    Java实现多线程下载和断点续传

    1. 把每个下载文件切成若干个块(Block),然后得到一个位图,用来标记每个块的下载情况,并保存到文件里,用于实现断点续传。 2. HTTP Header里增加Range,如果服务器返回Cotent-Range 说明服务器支持文件定位,可以...

    自己收集的多个Java FTP断点续传的例子源码

    java实现FTP多线程断点续传,上传下载! - java学习与交流 - j2ee学习网 - j2ee学习网 (2012年5月21日) 用 Java 实现断点续传 (HTTP) (2012年5月21日) Java写的支持断点续传的FTP--crybaby的博客 (2012年5月21日) ...

    java实现FTP多线程断点续传

    ### Java实现FTP多线程断点续传:深入解析与技术要点 在现代软件开发中,数据传输是一项基本且关键的任务,特别是在处理大文件时,断点续传功能显得尤为重要。断点续传允许在网络连接中断后恢复传输,避免了重新...

    java socket 多线程 断点续传实现

    最近研究了一下socket套接字 实现java多线程 断点续传文件 在网上查找了很多例子 然后学习了大家的方法 最后利用网上的例子 自己整合了一份多线程 断点续传文件的代码 并且能实现客户端发送完毕之后 接收服务器端的...

    Java多线程与线程安全实践-基于Http协议的断点续传

    下面是一个简单的Java多线程断点续传实现示例: ```java public class MultiThreadedDownload { private final int chunkSize; private final URL url; private final File outputFile; public ...

    Java毕业设计-多线程与线程安全实践-基于Http协议的断点续传.zip

    【标题】"Java毕业设计-多线程与线程安全实践-基于Http协议的断点续传.zip"涉及的核心知识点主要包括Java多线程编程、线程安全、HTTP协议以及文件的断点续传技术。 Java多线程编程是Java语言的一大特性,它允许程序...

    多线程断点续传工具类

    "多线程断点续传工具类"通常指的是一个Java类,该类设计用于实现文件传输时的多线程功能,并且能够从上次中断的地方继续下载或上传,这在大文件传输中非常有用,因为它可以提高速度并避免因网络问题导致的传输失败。...

    多线程断点续传(基于HTTP协议).zip_http 断点上传_http 断点续传_多线程断点续传_断点上传_断点续传

    同时,"【成品】多线程断点续传工具.jar"可能是一个可执行的Java应用程序,它提供了用户界面或者命令行工具,让用户可以方便地进行断点续传的文件上传。 多线程断点续传进一步提高了文件传输的效率。通过将文件分割...

    支持断点续传java多线程下载.doc

    综上,这个Java多线程断点续传的实现涉及了Java多线程编程的核心概念,包括线程创建、同步、通信和状态管理,以及网络I/O和文件操作。同时,为了提供用户友好的界面,还涉及到UI更新和进度反馈的实现。

    点对点多线程断点续传的实现

    总结的教程文档"点对点多线程断点续传的实现.doc"可能详细阐述了这些技术的实现细节,包括具体编程语言(如Java、C++或Python)的实现示例,以及如何将这些技术整合到实际应用中。而"www.pudn.com.txt"可能是该教程...

    java开发的多线程断点续传下载demo

    这个是java开发的多线程断点续传下载demo,内有详细注释,是练习android多线程断点续传下载时写的测试demo,下面的android开发的多线程断点续传下载demo是基于这个移植过去的,使用java开发的可以参考这个。

Global site tag (gtag.js) - Google Analytics