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

解决方案 »

  1.   

    这是我做的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();
    }
    }
    }
    }
      

  2.   

    地址:http://blog.csdn.net/shimiso/article/details/5956314
      

  3.   

    基本上别想了,如果单纯地使用 HTML 的上传是不可能做到的。
      

  4.   

    伙计,我可没说单纯使用HTML代码
      

  5.   

    这个可以通过第三方控件来实现。像QQ邮箱中的大附件上传,115网盘中的断点续传控件,139邮箱中的大文件断点续传控件都是使用ActiveX控件来实现的。
    此控件支持2G文件的断点续传操作,提供了完善的开发文档,支持文件MD5验证,支持文件批量上传。
    文件MD5值计算进度:文件MD5值计算完毕文件上传中文件上传完毕
      

  6.   

    我在网上看到过一个类似控件,叫Xproer.HttpUploader3,你可以试一下。http://www.cnblogs.com/xproer/archive/2012/02/17/2355440.html
      

  7.   

    断点续传和WEB服务端的关系不大,主要是客户端的事情。
    一般断点续传的实现是将一个大文件分成多个小块,然后一小块一小块上传。在HTML中并没有提供这种文件分块的功能,所以普通HTML是没办法实现的。只能借助于控件来实现。
    QQ是将文件以128KB为单位分成若干个小块,然后每次向服务器POST一小块。并附带文件相关信息,比如MD5,文件块起始位置,文件总大小,这样服务端就能够根据这些信息来将每一小块文件拼接成一个完整的文件。