斷點下載文件Java代碼

jopen 9年前發布 | 2K 次閱讀 Java

使用標準的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;
}

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!