断点下载文件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; 
    } 
  
}

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10615.html

(0)
上一篇 2021年7月19日 10:21
下一篇 2021年7月19日 10:21

相关推荐

发表回复

登录后才能评论