首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

j2EE怎么实现文件的断点续传

2012-02-25 
j2EE如何实现文件的断点续传我想做一个能支持断点续传的上传下载功能,不过听说struts2不能实现断点续传,还

j2EE如何实现文件的断点续传
我想做一个能支持断点续传的上传下载功能,不过听说struts2不能实现断点续传,还请各位高手来指点指点,如果有代码最好给我贴出代码,本来我不喜欢让别人给源码的,不过这次做了比较久,所以不懂得地方很多,还请各位能为小弟解决这个问题。

[解决办法]
这是我做的android上的代码,希望对你有帮助:
1>首先得到下载文件的长度,然后设置本地文件的长度。
HttpURLConnection.getContentLength();
RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");
file.setLength(filesize);//设置本地文件的长度与要下载文件的长度是相等的
2>根据文件长度和线程数计算每条线程下载的数据长度和下载位置。如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如上图所示。
3>使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止,代码如下:
HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");
4>保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd");
threadfile.seek(2097152);//从文件的什么位置开始写入数据
而如果上面的不能被整除,例如10个字节分3个线程的话,那么前两个线程下载4个字节,最后一个线程下载2个字节。
每条线程下载的数据长度为:文件的总大小%线程数==0?文件的总大小/线程数:文件的总大小/线程数+1
计算某条线程应该从文件的什么位置开始下载到什么位置结束:
开始位置公式:n*length;
结束为位置公式:(n+1)*length-1(n为表示线程的索引值第一个为0,length为每条线程下载的长度);

public class FileDownLoader {
@Test
public void download() throws Exception {
String path = "http://net.itcast.cn/QQWubiSetup.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5*1000);
conn.setRequestMethod("GET");
conn.setRequestProperty("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, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Connection", "Keep-Alive");
System.out.println(conn.getResponseCode());

int filesize = conn.getContentLength();//得到文件大小
conn.disconnect();
int threasize = 3;//线程数
int perthreadsize = filesize / 3 + 1;
RandomAccessFile file = new RandomAccessFile("102.wma","rw");
file.setLength(filesize);//设置本地文件的大小
file.close();
for(int i=0; i<threasize ; i++){
int startpos = i * perthreadsize;//计算每条线程的下载位置
RandomAccessFile perthreadfile = new RandomAccessFile("102.wma","rw");//
perthreadfile.seek(startpos);//从文件的什么位置开始写入数据
new DownladerThread(i, path, startpos, perthreadsize, perthreadfile).start();
}
//以下代码要求用户输入q才会退出测试方法,如果没有下面代码,会因为进程结束而导致进程内的下载线程被销毁
int quit = System.in.read();
while('q'!=quit){
Thread.sleep(2 * 1000);
}
}

private class DownladerThread extends Thread{
private int startpos;//从文件的什么位置开始下载
private int perthreadsize;//每条线程需要下载的文件大小
private String path;
private RandomAccessFile file;
private int threadid;

public DownladerThread(int threadid, String path, int startpos, int perthreadsize, RandomAccessFile perthreadfile) {
this.path = path;
this.startpos = startpos;
this.perthreadsize = perthreadsize;
this.file = perthreadfile;
this.threadid = threadid;
}

@Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");


conn.setRequestProperty("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, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Range", "bytes=" + this.startpos + "-");
InputStream inStream = conn.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
int length = 0;
while(length<perthreadsize && (len = inStream.read(buffer))!=-1){
file.write(buffer, 0, len);
length += len;//累计该线程下载的总大小
}
file.close();
inStream.close();
System.out.println(threadid+ "线程完成下载");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

[解决办法]
请参考这篇博文,代码直接调试可运行,有问题随时沟通Q群:173711587
[解决办法]
地址:http://blog.csdn.net/shimiso/article/details/5956314

热点排行