断点下载文件Java代码

2018-07-20    来源:open-open

容器云强势上线!快速搭建集群,上万Linux镜像随意使用
使用标准的JDK方法编写的下载,不含其它开源控件。
package common.http.down;
 
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class DownFile {
 
    private static final Log log = LogFactory.getLog(DownFile.class);
    private static boolean running; // 是否运行中,避免线程不能释放
    private static Long fileLength = 0L;//文件的大小
    private static Long bytesum = 0L;//已获取的文件大小
    private static Long ssll = 0L;//当前传输流量
    private static long beginTime;//开始下载时间
    public DownFile() {
    }
 
    public static Long getFileSize(URL url) throws IOException{
        //获取一些参数
        HttpURLConnection checkurlconn = getHttpConnection(url,0);
        String contentLength = checkurlconn.getHeaderField("Content-Length");
        checkurlconn.disconnect();
        if (contentLength != null) {
            try {
                return Long.parseLong(contentLength);
            } catch (Exception e) {
            }
        }
        return 0L;
    }
     
    public static String getFileName(String urlpath){
        String filename = urlpath.substring(urlpath.lastIndexOf("/")+1);
        if(filename.indexOf("?")>=0){
            filename = filename.substring(0, filename.indexOf("?"));
        }
        return filename;
         
    }
     
    public static void downloadNet() throws IOException {
        // 下载网络文件
        int byteread = 0;
        beginTime = System.currentTimeMillis();
        MonitorThread monitorThread = new MonitorThread();
        String urlpath = "http://dldir1.qq.com/qqfile/qq/QQ7.3/15034/QQ7.3.exe";
        //urlpath = "http://archive.apache.org/dist/tomcat/tomcat-8/v8.0.9/bin/apache-tomcat-8.0.9-windows-x64.zip";
        URL url = new URL(urlpath);
        fileLength =getFileSize(url);
        String filename = getFileName(urlpath);
        RandomAccessFile destFile = new RandomAccessFile("c:/"+filename, "rw");
        bytesum =destFile.length(); 
        if(bytesum>0&&bytesum.equals(fileLength)){
            destFile.close();
            throw new IOException("文件已被下载完成!");
        }
        HttpURLConnection httpUrlConnection = getHttpConnection(url,bytesum);
        if(httpUrlConnection.getHeaderField("Content-Range")==null){
            log.info("当前网站不支持续传");
            destFile.seek(0);
            bytesum=0L;
        }
 
        if(bytesum>0){//文件已存在,判断是否需要下载
            log.info(filename+"已下载了"+getFileSize(bytesum)+"继续下载!");
            destFile.seek(bytesum);
        }
 
        try {
            running = true;
            monitorThread.start();
            InputStream inStream = httpUrlConnection.getInputStream();
            byte[] buffer = new byte[1204];
            while ((byteread = inStream.read(buffer)) != -1) {
                bytesum += byteread;
                ssll += byteread;
                destFile.write(buffer, 0, byteread);
            }
            running = false;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            destFile.close();
        }
    }
 
    private static HttpURLConnection getHttpConnection(URL url,long pos)
            throws IOException {
        // 默认的会处理302请求
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection httpConnection = null;
        httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.setRequestProperty("RANGE", "bytes=" + pos + "-");
        int responseCode = httpConnection.getResponseCode();
        log.debug("服务器返回:" + responseCode);
        Map<String, List<String>> headers = httpConnection.getHeaderFields();
        Iterator<String> iterator = headers.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = "";
            for (String v : headers.get(key)) {
                value = ";" + v;
            }
            log.debug(key + "=" + value);
        }
        if (responseCode < 200 || responseCode >= 400) {
            throw new IOException("服务器返回无效信息:" + responseCode);
        }
        return httpConnection;
    }
 
    public static void main(String[] args) {
        try {
            downloadNet();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    private static class MonitorThread extends Thread {
        public void run() {
            try {
                while (running) {
                    log.info(getDesc());//打印进度
                    ssll = 0L;
                    sleep(1000);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e);
            } finally {
 
            }
        }
    }
    private static String getDesc() {
        return String.format("已下载/总大小=%s/%s(%s),速度:%s,耗时:%s,剩余大小:%s,大约需要:%s",
                getFileSize(bytesum),
                getFileSize(fileLength),
                getProgress(fileLength, bytesum),
                getFileSize(ssll),
                getTime((System.currentTimeMillis() - beginTime) / 1000),
                getFileSize(fileLength - bytesum),
                (ssll==0?"未知":getTime((fileLength - bytesum) / ssll)));
    }
 
    private static String getFileSize(long totals) {
        // 计算文件大小
        int i = 0;
        String j = "BKMGT";
        float s = totals;
        while (s > 1024) {
            s /= 1024;
            i++;
        }
        return String.format("%.2f", s) + j.charAt(i);
    }
 
    private static String getProgress(long totals, long read) {
        if (totals == 0)
            return "0%";
        return String.format("%d", read * 100 / totals) + "%";
    }
 
    private static String getTime(long seconds) {
        int i = 0;
        String j = "秒分时天";
        long s = seconds;
        String result = "";
        while (s > 0) {
            if (s % 60 > 0) {
                result = String.valueOf(s % 60) + (char) j.charAt(i) + result;
            }
            s /= 60;
            i++;
        }
        return result;
    }
 
}

标签: ssl 服务器 网络

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇:利用Java Mail发送邮件的代码

下一篇:Android天天数钱游戏源码