Java实现文件断点续传

打印 上一主题 下一主题

主题 923|帖子 923|积分 2769

文件断点续传代码
  1. import java.io.File;
  2. import java.io.FileNotFoundException;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.RandomAccessFile;
  6. import java.net.HttpURLConnection;
  7. import java.net.MalformedURLException;
  8. import java.net.URL;
  9. import java.util.Date;
  10. public class DT extends Thread {
  11.     String urlt;//下载地址
  12.     int startl;//子线程读取/写入起始字节
  13.     int end;//子线程写入结束字节长度
  14.     String fileName;
  15.     RandomAccessFile osf;
  16.     public DT(int i, String url, String fileName, int start, int end) {
  17.         this.setName("t" + i); //子线程名称
  18.         this.urlt = url; //下载地址
  19.         this.fileName = fileName;
  20.         this.startl = start; //子线程读取/写入起始字节
  21.         this.end = end;//子线程写入结束字节长度
  22.     }
  23.     public void run() {
  24.         try {
  25.             osf = new RandomAccessFile(fileName, "rw");
  26.             URL url = new URL(urlt);
  27.             HttpURLConnection http2 = (HttpURLConnection) url.openConnection();
  28.             http2.setRequestProperty("User-Agent", "NetFox");
  29.             /*
  30.              * 断点续传和多线程下载的关键代码关键位置:即设置断点
  31.              * http2.setRequestProperty("RANGE", "bytes="+startl+"-");//设置断点位置,向服务器请求从文件的哪个字节开始读取。
  32.              * osf.seek(startl);//设置本地文件从哪个字节开始写入
  33.              * 如果是单线程,则首先要判断下载文件是否已经存在 及DownloadFile.java 里的 fileName = "C:\eclipse.zip";
  34.              * 如果存在则开始断点续传,方法同多线程:
  35.              * 因为断点续传是从上次传输中断的字节开始,则首先要得到上次中断的位置,既是文件长度(针对单线程)f.length()
  36.              * 然后设置HTTP请求头属性RANGE,该属性告知服务器从哪个自己开始读取文件。
  37.              * 设置本地文件写入起始字节,及接从上次传输断点继续写入(断点续传)
  38.              * osf.seek(offset) 该方法设定从offset后一个字节开始写入文件
  39.              * 注意:多线程不能用文件长度做为写文件起始字节,需有配置文件记录上次读写的位置,迅雷下载既是使用该种方法。
  40.              *
  41.              */
  42.             http2.setRequestProperty("RANGE", "bytes=" + startl + "-");//设置断点位置,向服务器请求从文件的哪个字节开始读取。
  43.             osf.seek(startl);//设置本地文件从哪个字节开始写入
  44.             InputStream input = http2.getInputStream();
  45.             byte b[] = new byte[1024];//设置缓冲池,每次只读1024字节
  46.             Date d = new Date();//子线程开始下载时间
  47.             int l;//计算子线程读取和写入的文件长度,当长度大于每个子线程平均下载长度则终止线程
  48.             int i;
  49.             l = 0;
  50.             System.out.println(this.getName() + " 开始下载。。。");
  51.             while ((i = input.read(b, 0, 1024)) != -1 && l < end) {    //线程下载字节长度控制误差小于缓冲池大小,本示例为缓冲池1024字节
  52.                 osf.write(b, 0, i);
  53.                 b = new byte[1024];//重新赋值,避免重新读入旧内容
  54.                 l += i;
  55.             }
  56.             Date d2 = new Date();//子线程结束下载时间
  57.             System.out.println(this.getName() + " 线程耗时: " + (d2.getTime() - d.getTime()) / 1000 + " 秒,实际共下载:" + l + "字节");//子线程下载耗时(秒)
  58.         } catch (FileNotFoundException e1) {
  59.             // TODO Auto-generated catch block
  60.             e1.printStackTrace();
  61.         } catch (MalformedURLException e) {
  62.             // TODO Auto-generated catch block
  63.             e.printStackTrace();
  64.         } catch (IOException e) {
  65.             // TODO Auto-generated catch block
  66.             e.printStackTrace();
  67.         }
  68.     }
  69. }
复制代码
测试代码
  1. import java.io.*;
  2. import java.net.HttpURLConnection;
  3. import java.net.MalformedURLException;
  4. import java.net.URL;
  5. public class DownloadFile {
  6.     /**
  7.      * @param args
  8.      */
  9.     static int len;//线程平均下载文件长度
  10.     static int bn ;//每个线程写入文件的字节数
  11.     static int tn; //线程数
  12.     static String urlt;//下载地址
  13.     static String fileName;
  14.     static RandomAccessFile osf; //文件操作
  15.     public static void main(String[] args) {
  16.         // TODO Auto-generated method stub
  17.         try {
  18.             urlt = "http://192.168.16.77:8080/Stargreat/html/baidu player";
  19.             fileName = "C:" + urlt.split("//")[1].split("/")[urlt.split("//")[1].split("/").length-1];
  20.             System.out.println(fileName);
  21.             URL url = new URL(urlt);
  22.             HttpURLConnection http = (HttpURLConnection) url.openConnection();
  23.             /**
  24.              * 此处设定5个线程下载一个文件tn = 5;
  25.              * 判断平均每个线程需下载文件长度:
  26.              */
  27.             System.out.println("file size:" + http.getContentLength());
  28.             tn = 3;
  29.             len = http.getContentLength() / tn ;//舍去余数(余数自动舍去)计算每个线程应下载平均长度,最后一个线程再加上余数,则是整个文件的长度,
  30.             File f = new File(fileName);
  31.             if (f.exists()){
  32.                 f.delete();
  33.                 osf = new RandomAccessFile(f, "rw");
  34.                 osf.seek(http.getContentLength()-1);
  35.                 osf.write(0);
  36.             }else{
  37.                 osf = new RandomAccessFile(f, "rw");
  38.                 osf.seek(http.getContentLength()-1);
  39.                 osf.write(0);
  40.             }
  41.             System.out.println("temp 文件长度:" + f.length());
  42.             Thread t;//下载子线程,
  43.             for (int j = 0; j < tn; j++) {
  44.                 if(j == tn - 1){//如果最后一个线程则加上余数长度字节
  45.                     bn = len + (http.getContentLength() % tn);
  46.                 }else{
  47.                     bn = len;
  48.                 }
  49.                 System.out.println("t"+ j + "线程下载长度:" + bn + "起始字节:" + len*j);
  50.                 t = new DT(
  51.                         j,
  52.                         urlt,
  53.                         fileName,
  54.                         len*j,
  55.                         bn
  56.                 );
  57.                 t.start();
  58.             }
  59.         } catch (IOException e) {
  60.             // TODO Auto-generated catch block
  61.             e.printStackTrace();
  62.         }
  63.     }
  64. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

反转基因福娃

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表