服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用java 实现 http 的断点续传


  java 实现 http 的断点续传
东方快骑阿乐飞扬 2002-8-13 合肥整理

说明:
1) filesplitterfetch类 负责整个文件的抓取,控制内部线程;
2) randomaccessfile类用于在任意一个文件的特定位置上读/写字节

/*
sitefilefetch.java
*/
package netfox; //download please
import java.io.*;
import java.net.*;
public class sitefilefetch extends thread {
siteinfobean siteinfobean = null; //文件信息bean
long[] nstartpos; //开始位置
long[] nendpos; //结束位置
filesplitterfetch[] filesplitterfetch; //子线程对象
long nfilelength; //文件长度
boolean bfirst = true; //是否第一次取文件
boolean bstop = false; //停止标志
file tmpfile; //文件下载的临时信息
dataoutputstream output; //输出到文件的输出流
//负责整个文件的抓取,控制内部线程
public sitefilefetch(siteinfobean bean) throws ioexception{
siteinfobean = bean;
//tmpfile = file.createtempfile ("zhong","1111",new file(bean.getsfilepath()));
tmpfile = new file(bean.getsfilepath()+file.separator + bean.getsfilename()+".info");
if(tmpfile.exists ()){
bfirst = false;
read_npos();
}
else{
nstartpos = new long[bean.getnsplitter()];
nendpos = new long[bean.getnsplitter()];
}
}
public void run()
{
//获得文件长度
//分割文件
//实例filesplitterfetch
//启动filesplitterfetch线程
//等待子线程返回
try{
if(bfirst)
{
nfilelength = getfilesize();
if(nfilelength == -1)
{
system.err.println("file length is not known!");
}
else if(nfilelength == -2)
{
system.err.println("file is not access!");
}
else
{
for(int i=0;i<nstartpos.length;i++)
{
nstartpos[i] = (long)(i*(nfilelength/nstartpos.length));
}
for(int i=0;i<nendpos.length-1;i++)
{
nendpos[i] = nstartpos[i+1];
}
nendpos[nendpos.length-1] = nfilelength;
}
}
//启动子线程
filesplitterfetch = new filesplitterfetch[nstartpos.length];
for(int i=0;i<nstartpos.length;i++){
filesplitterfetch[i] = new filesplitterfetch(siteinfobean.getssiteurl(),
siteinfobean.getsfilepath() + file.separator + siteinfobean.getsfilename(),
nstartpos[i],nendpos[i],i);
utility.log("thread " + i + " , nstartpos = " + nstartpos[i] + ", nendpos = " + nendpos[i]);
filesplitterfetch[i].start();
}
// filesplitterfetch[npos.length-1] = new filesplitterfetch(siteinfobean.getssiteurl(),
siteinfobean.getsfilepath() + file.separator + siteinfobean.getsfilename(),npos[npos.length-1],nfilelength,npos.length-1);
// utility.log("thread " + (npos.length-1) + " , nstartpos = " + npos[npos.length-1] + ",
nendpos = " + nfilelength);
// filesplitterfetch[npos.length-1].start();
//等待子线程结束
//int count = 0;
//是否结束while循环
boolean breakwhile = false;
while(!bstop){
write_npos();
utility.sleep(500);
breakwhile = true;
for(int i=0;i<nstartpos.length;i++){
if(!filesplitterfetch[i].bdownover){
breakwhile = false;
break;
}
}
if(breakwhile)
break;


//count++;
//if(count>4)
// sitestop();
}
system.err.println("文件下载结束!");}
catch(exception e){e.printstacktrace ();
}
}


//获得文件长度
public long getfilesize(){
int nfilelength = -1;
try{
url url = new url(siteinfobean.getssiteurl());
httpurlconnection httpconnection = (httpurlconnection)url.openconnection ();
httpconnection.setrequestproperty("user-agent","netfox");
int responsecode=httpconnection.getresponsecode();
if(responsecode>=400){
processerrorcode(responsecode);
return -2; //-2 represent access is error
}


string sheader;
for(int i=1;;i++){
//datainputstream in = new datainputstream(httpconnection.getinputstream ());
//utility.log(in.readline());
sheader=httpconnection.getheaderfieldkey(i);
if(sheader!=null){
if(sheader.equals("content-length")){
nfilelength = integer.parseint(httpconnection.getheaderfield(sheader));
break;
}
}
else
break;
}
}
catch(ioexception e){e.printstacktrace ();}
catch(exception e){e.printstacktrace ();}
utility.log(nfilelength);
return nfilelength;
}
//保存下载信息(文件指针位置)
private void write_npos(){
try{
output = new dataoutputstream(new fileoutputstream(tmpfile));
output.writeint(nstartpos.length);
for(int i=0;i<nstartpos.length;i++){
// output.writelong(npos[i]);
output.writelong(filesplitterfetch[i].nstartpos);
output.writelong(filesplitterfetch[i].nendpos);
}
output.close();
}
catch(ioexception e){e.printstacktrace ();}
catch(exception e){e.printstacktrace ();}
}
//读取保存的下载信息(文件指针位置)
private void read_npos(){
try{
datainputstream input = new datainputstream(new fileinputstream(tmpfile));
int ncount = input.readint();
nstartpos = new long[ncount];
nendpos = new long[ncount];
for(int i=0;i<nstartpos.length;i++){
nstartpos[i] = input.readlong();
nendpos[i] = input.readlong();
}
input.close();
}
catch(ioexception e){e.printstacktrace ();}
catch(exception e){e.printstacktrace ();}
}
private void processerrorcode(int nerrorcode){
system.err.println("error code : " + nerrorcode);
}
//停止文件下载
public void sitestop(){
bstop = true;
for(int i=0;i<nstartpos.length;i++)
filesplitterfetch[i].splitterstop();
}
}
//负责部分文件的抓取
**filesplitterfetch.java
*/
package netfox;
import java.io.*;
import java.net.*;
public class filesplitterfetch extends thread {
string surl; //file url
long nstartpos; //file snippet start position
long nendpos; //file snippet end position
int nthreadid; //thread´s id
boolean bdownover = false; //downing is over
boolean bstop = false; //stop identical
fileaccessi fileaccessi = null; //file access interface


public filesplitterfetch(string surl,string sname,long nstart,long nend,int id) throws ioexception{
this.surl = surl;
this.nstartpos = nstart;
this.nendpos = nend;
nthreadid = id;
fileaccessi = new fileaccessi(sname,nstartpos);//定位
}


public void run(){
while(nstartpos < nendpos && !bstop){
try{
url url = new url(surl);
httpurlconnection httpconnection = (httpurlconnection)url.openconnection ();
httpconnection.setrequestproperty("user-agent","netfox");
string sproperty = "bytes="+nstartpos+"-";
httpconnection.setrequestproperty("range",sproperty);
utility.log(sproperty);
inputstream input = httpconnection.getinputstream();
//logresponsehead(httpconnection);
byte[] b = new byte[1024];
int nread;
while((nread=input.read(b,0,1024)) > 0 && nstartpos < nendpos && !bstop){
nstartpos += fileaccessi.write(b,0,nread);
//if(nthreadid == 1)
// utility.log("nstartpos = " + nstartpos + ", nendpos = " + nendpos);
}
utility.log("thread " + nthreadid + " is over!");
bdownover = true;
//npos = fileaccessi.write (b,0,nread);
}
catch(exception e){e.printstacktrace ();}
}
}
//打印回应的头信息
public void logresponsehead(httpurlconnection con){
for(int i=1;;i++){
string header=con.getheaderfieldkey(i);
if(header!=null)
//responseheaders.put(header,httpconnection.getheaderfield(header));
utility.log(header+" : "+con.getheaderfield(header));
else
break;
}
}


public void splitterstop(){
bstop = true;
}
}
/*
**fileaccess.java
*//文件访问(定位,写)
package netfox;
import java.io.*;
public class fileaccessi implements serializable{
//randomaccessfile类用于在任意一个文件的特定位置上读/写字节
randomaccessfile osavedfile;
long npos;
public fileaccessi() throws ioexception{
this("",0);
}
public fileaccessi(string sname,long npos) throws ioexception{
osavedfile = new randomaccessfile(sname,"rw");
this.npos = npos;
osavedfile.seek(npos);
}
public synchronized int write(byte[] b,int nstart,int nlen){
int n = -1;
try{
osavedfile.write(b,nstart,nlen);
n = nlen;
}
catch(ioexception e){
e.printstacktrace ();
}
return n;
}
}
/*
**siteinfobean.java
*/
package netfox;
public class siteinfobean {
private string ssiteurl; //site´s url
private string sfilepath; //saved file´s path
private string sfilename; //saved file´s name
private int nsplitter; //count of splited downloading file
public siteinfobean()
{//nsplitter的缺省值为5
//default value of nsplitter is 5
this("","","",5);
}
public siteinfobean(string surl,string spath,string sname,int nspiltter){
ssiteurl= surl;
sfilepath = spath;
sfilename = sname;
this.nsplitter = nspiltter;
}
public string getssiteurl(){
return ssiteurl;
}
public void setssiteurl(string value){
ssiteurl = value;
}
public string getsfilepath(){
return sfilepath;
}
public void setsfilepath(string value){
sfilepath = value;
}
public string getsfilename(){
return sfilename;
}
public void setsfilename(string value){
sfilename = value;
}
public int getnsplitter(){
return nsplitter;
}
public void setnsplitter(int ncount){
nsplitter = ncount;
}
}
/*
**utility.java
*/
package netfox;
public class utility {
public utility(){
}
//线程睡眠
public static void sleep(int nsecond){
try{
thread.sleep(nsecond);
}
catch(exception e){
e.printstacktrace ();
}
}
//日志
public static void log(string smsg){
system.err.println(smsg);
}
public static void log(int smsg){
system.err.println(smsg);
}
}
/*
**testmethod.java
*/
package netfox;
public class testmethod {
public testmethod()
{ ///xx/weblogic60b2_win.exe
try{
siteinfobean bean = new siteinfobean("http://localhost/xx/weblogic60b2_win.exe","l:/temp","weblogic60b2_win.exe",5);
//siteinfobean bean = new siteinfobean("http://localhost:8080/down.zip","l:/temp","weblogic60b2_win.exe",5);
sitefilefetch filefetch = new sitefilefetch(bean);
filefetch.start();
}
catch(exception e){e.printstacktrace ();}
}
public static void main(string args[]){
new testmethod();
}
}

扫描关注微信公众号