请求头中包含如下 RANGE:bytes=2345-
意思是从2345字节处开始请求数据。这样如果在xx处下载失败,可以通过传递如上请求参数达到续传的目的。
DownloadApp
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Act:
* User:于勇
* Date: 12-12-24
* version:1.0
* To change this template use File | Settings | File Templates.
*/
public class DownloadTask extends Thread{
private DownloadInfo info;
private long start;
private long length;
public DownloadTask(DownloadInfo info){
this.info=info;
}
public DownloadTask(DownloadInfo info,long start,long length){
this.info=info;
this.start=start;
this.length=length;
System.out.println("线程 "+this.getId()+" 开启");
}
@Override
public void run() {
long tmpLen=0;
InputStream input=null;
RandomAccessFile tmpSaveFile=null;
try{
URL url=new URL(info.getdSourcePath());
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
String sProperty="bytes="+start+"-";
httpURLConnection.setRequestProperty("User-Agent","NetFox");
httpURLConnection.setRequestProperty("RANGE", sProperty);
input = httpURLConnection.getInputStream();
byte[]b=new byte[DownloadInfo.THREAD_READ_LENGTH];
int nRead;
File tmpFile=new File(info.getdSavePath()+File.separator+info.getdSaveName()+".tmp");
tmpSaveFile = new RandomAccessFile(tmpFile,"rw");
if(tmpFile.exists()){
tmpSaveFile.seek(start);
}
while((nRead=input.read(b,0,DownloadInfo.THREAD_READ_LENGTH))>0&&tmpLen<length){
tmpLen+=nRead;
tmpSaveFile.write(b,0,nRead);
}
System.out.println("线程 "+this.getId()+" 下载完成!下载片段["+this.start+"字节至"+(this.start+length)+"字节]");
}catch(Exception e){
System.out.println("线程 "+this.getId()+" 出错");
DownloadTask task=new DownloadTask(info,start+tmpLen,length-tmpLen);
task.start();
DownloadProject.totalThread++;
System.out.println("线程 "+task.getId()+" 开启恢复 从 "+(start+tmpLen)+" ");
}finally{
try {
input.close();
tmpSaveFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DownloadProject.totalThread--;
}
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
public DownloadInfo getInfo() {
return info;
}
public void setInfo(DownloadInfo info) {
this.info = info;
}
public long getStart() {
return start;
}
public void setStart(long start) {
this.start = start;
}
}
DownloadInfo
/**
* Act:
* User:于勇
* Date: 12-12-24
* version:1.0
* To change this template use File | Settings | File Templates.
*/
public class DownloadInfo {
private String dSourcePath;
private String dSaveName;
private String dSavePath;
public static long THREAD_LENGTH=4096;//1024000
public static int THREAD_READ_LENGTH=2048
;
public DownloadInfo(String sourcePath,String savePath,String saveName){
this.dSourcePath=sourcePath;
this.dSaveName=saveName;
this.dSavePath=savePath;
}
public String getdSourcePath() {
return dSourcePath;
}
public void setdSourcePath(String dSourcePath) {
this.dSourcePath = dSourcePath;
}
public String getdSaveName() {
return dSaveName;
}
public void setdSaveName(String dSaveName) {
this.dSaveName = dSaveName;
}
public String getdSavePath() {
return dSavePath;
}
public void setdSavePath(String dSavePath) {
this.dSavePath = dSavePath;
}
}
DownloadProject
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Act:
* User:于勇
* Date: 12-12-24
* version:1.0
* To change this template use File | Settings | File Templates.
*/
public class DownloadProject extends Thread{
public static int totalThread=0;
private DownloadInfo info;
public void setInfo(DownloadInfo info) {
this.info = info;
}
@Override
public void run() {
try{
runThreads();
while(totalThread>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
switchFile();
}
}
private void runThreads(){
try{
URL url=new URL(info.getdSourcePath());
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
String sProperty="bytes="+0+"-";
httpURLConnection.setRequestProperty("RANGE", sProperty);
InputStream input= httpURLConnection.getInputStream();
int length=httpURLConnection.getContentLength();
File tmpFile=new File(info.getdSavePath()+File.separator+info.getdSaveName()+".tmp");
long start=0;
long compLen=0;
if(tmpFile.exists()){
compLen=tmpFile.length();
if(compLen<length){
start+=compLen;
length-=compLen;
}else
return;
}
for(int i=1;i<=length/DownloadInfo.THREAD_LENGTH;i++){
DownloadTask task=null;
task=new DownloadTask(info,start,DownloadInfo.THREAD_LENGTH);
task.start();
totalThread++;
start=start+DownloadInfo.THREAD_LENGTH;
}
if(length%DownloadInfo.THREAD_LENGTH!=0){
DownloadTask task=new DownloadTask(info,start,length%DownloadInfo.THREAD_LENGTH);
task.start();
totalThread++;
start+=length%DownloadInfo.THREAD_LENGTH;
}
input.close();
}catch(Exception e){
e.printStackTrace();
}
}
private void switchFile(){
File oldfile=new File(info.getdSavePath()+File.separator+info.getdSaveName()+".tmp");
File newfile=new File(info.getdSavePath()+File.separator+info.getdSaveName());
oldfile.renameTo(newfile);
}
}
DownloadTask
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Act:
* User:于勇
* Date: 12-12-24
* version:1.0
* To change this template use File | Settings | File Templates.
*/
public class DownloadTask extends Thread{
private DownloadInfo info;
private long start;
private long length;
public DownloadTask(DownloadInfo info){
this.info=info;
}
public DownloadTask(DownloadInfo info,long start,long length){
this.info=info;
this.start=start;
this.length=length;
System.out.println("线程 "+this.getId()+" 开启");
}
@Override
public void run() {
long tmpLen=0;
InputStream input=null;
RandomAccessFile tmpSaveFile=null;
try{
URL url=new URL(info.getdSourcePath());
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
String sProperty="bytes="+start+"-";
httpURLConnection.setRequestProperty("User-Agent","NetFox");
httpURLConnection.setRequestProperty("RANGE", sProperty);
input = httpURLConnection.getInputStream();
byte[]b=new byte[DownloadInfo.THREAD_READ_LENGTH];
int nRead;
File tmpFile=new File(info.getdSavePath()+File.separator+info.getdSaveName()+".tmp");
tmpSaveFile = new RandomAccessFile(tmpFile,"rw");
if(tmpFile.exists()){
tmpSaveFile.seek(start);
}
while((nRead=input.read(b,0,DownloadInfo.THREAD_READ_LENGTH))>0&&tmpLen<length){
tmpLen+=nRead;
tmpSaveFile.write(b,0,nRead);
}
System.out.println("线程 "+this.getId()+" 下载完成!下载片段["+this.start+"字节至"+(this.start+length)+"字节]");
}catch(Exception e){
System.out.println("线程 "+this.getId()+" 出错");
DownloadTask task=new DownloadTask(info,start+tmpLen,length-tmpLen);
task.start();
DownloadProject.totalThread++;
System.out.println("线程 "+task.getId()+" 开启恢复 从 "+(start+tmpLen)+" ");
}finally{
try {
input.close();
tmpSaveFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DownloadProject.totalThread--;
}
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
public DownloadInfo getInfo() {
return info;
}
public void setInfo(DownloadInfo info) {
this.info = info;
}
public long getStart() {
return start;
}
public void setStart(long start) {
this.start = start;
}
}
分享到:
相关推荐
Java多线程断点续传下载是一个复杂但实用的技术,尤其在处理大文件或网络不稳定时,能够提高用户体验并优化资源利用。以下是对这个主题的详细解析: **1. Java多线程** Java多线程是指在一个Java应用程序中同时执行...
下面将详细探讨如何在Java中实现多线程断点续传。 首先,我们需要理解多线程的概念。在Java中,我们可以使用`Thread`类或`Runnable`接口来创建线程。当一个线程被创建后,它可以与主线程并行运行,每个线程都有自己...
总结来说,Java实现的多线程断点续传涉及的技术点包括: 1. 并发编程:使用`ExecutorService`、`CountDownLatch`进行线程管理和同步。 2. 文件操作:分析和合并临时文件,实现断点续传。 3. 网络I/O:通过`...
Java多线程断点续传下载程序是一种高级的软件实现技术,它结合了Java的并发处理能力和文件传输的策略,以提高下载效率和用户体验。在这个项目中,我们主要关注两个核心概念:多线程和断点续传。 首先,多线程是Java...
然而,实现多线程断点续传需要解决几个问题: 1. **同步管理**:多个线程可能会同时访问同一个文件的部分,因此需要使用`synchronized`关键字或`Lock`对象来确保并发安全。 2. **断点信息共享**:每个线程需要知道...
Java多线程断点续传是一种在网络编程中经常使用的文件下载技术。当网络下载过程中遇到意外情况,比如网络断开、用户退出,或者程序异常退出时,能够从上次中断的位置继续下载,而不是重新开始。利用Java多线程技术,...
通过以上步骤,我们可以构建一个功能完备的Java多线程断点续传下载程序。这个项目不仅可以帮助初学者理解多线程和网络编程的基本概念,也可以作为实际项目开发中的一个参考模板。对于想要深入研究Java网络编程和并发...
而"多线程"和"断点"这两个文件名可能是指相关示例代码或文档,可以进一步帮助你理解和实践Java FTP的多线程下载和断点续传。 在实际应用中,还需要考虑其他因素,如错误处理、网络状况的监控、文件完整性检查等。...
1. 把每个下载文件切成若干个块(Block),然后得到一个位图,用来标记每个块的下载情况,并保存到文件里,用于实现断点续传。 2. HTTP Header里增加Range,如果服务器返回Cotent-Range 说明服务器支持文件定位,可以...
java实现FTP多线程断点续传,上传下载! - java学习与交流 - j2ee学习网 - j2ee学习网 (2012年5月21日) 用 Java 实现断点续传 (HTTP) (2012年5月21日) Java写的支持断点续传的FTP--crybaby的博客 (2012年5月21日) ...
### Java实现FTP多线程断点续传:深入解析与技术要点 在现代软件开发中,数据传输是一项基本且关键的任务,特别是在处理大文件时,断点续传功能显得尤为重要。断点续传允许在网络连接中断后恢复传输,避免了重新...
最近研究了一下socket套接字 实现java多线程 断点续传文件 在网上查找了很多例子 然后学习了大家的方法 最后利用网上的例子 自己整合了一份多线程 断点续传文件的代码 并且能实现客户端发送完毕之后 接收服务器端的...
下面是一个简单的Java多线程断点续传实现示例: ```java public class MultiThreadedDownload { private final int chunkSize; private final URL url; private final File outputFile; public ...
【标题】"Java毕业设计-多线程与线程安全实践-基于Http协议的断点续传.zip"涉及的核心知识点主要包括Java多线程编程、线程安全、HTTP协议以及文件的断点续传技术。 Java多线程编程是Java语言的一大特性,它允许程序...
"多线程断点续传工具类"通常指的是一个Java类,该类设计用于实现文件传输时的多线程功能,并且能够从上次中断的地方继续下载或上传,这在大文件传输中非常有用,因为它可以提高速度并避免因网络问题导致的传输失败。...
同时,"【成品】多线程断点续传工具.jar"可能是一个可执行的Java应用程序,它提供了用户界面或者命令行工具,让用户可以方便地进行断点续传的文件上传。 多线程断点续传进一步提高了文件传输的效率。通过将文件分割...
综上,这个Java多线程断点续传的实现涉及了Java多线程编程的核心概念,包括线程创建、同步、通信和状态管理,以及网络I/O和文件操作。同时,为了提供用户友好的界面,还涉及到UI更新和进度反馈的实现。
总结的教程文档"点对点多线程断点续传的实现.doc"可能详细阐述了这些技术的实现细节,包括具体编程语言(如Java、C++或Python)的实现示例,以及如何将这些技术整合到实际应用中。而"www.pudn.com.txt"可能是该教程...
这个是java开发的多线程断点续传下载demo,内有详细注释,是练习android多线程断点续传下载时写的测试demo,下面的android开发的多线程断点续传下载demo是基于这个移植过去的,使用java开发的可以参考这个。