• 回家调试


    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;

    public class FileDown {
    /**
    * 说明:根据指定URL将文件下载到指定目标位置
    *
    * @param urlPath
    * 下载路径
    * @param downloadDir
    * 文件存放目录
    * @return 返回下载文件
    */
    @SuppressWarnings("finally")
    public static File downloadFile(String urlPath, String downloadDir) {
    File file = null;
    try {
    // 统一资源
    URL url = new URL(urlPath);
    // 连接类的父类,抽象类
    URLConnection urlConnection = url.openConnection();
    // http的连接类
    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
    //设置超时
    httpURLConnection.setConnectTimeout(1000*5);
    //设置请求方式,默认是GET
    httpURLConnection.setRequestMethod("GET");
    // 设置字符编码
    httpURLConnection.setRequestProperty("Charset", "UTF-8");
    // 打开到此 URL引用的资源的通信链接(如果尚未建立这样的连接)。
    httpURLConnection.connect();
    // 文件大小
    int fileLength = httpURLConnection.getContentLength();

    // 控制台打印文件大小
    System.out.println("您要下载的文件大小为:" + fileLength / (1024 * 1024) + "MB");

    // 建立链接从请求中获取数据
    URLConnection con = url.openConnection();
    BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());
    // 指定文件名称(有需求可以自定义)
    String fileFullName = "aaa.apk";
    // 指定存放位置(有需求可以自定义)
    String path = downloadDir + File.separatorChar + fileFullName;
    file = new File(path);
    // 校验文件夹目录是否存在,不存在就创建一个目录
    if (!file.getParentFile().exists()) {
    file.getParentFile().mkdirs();
    }

    OutputStream out = new FileOutputStream(file);
    int size = 0;
    int len = 0;
    byte[] buf = new byte[2048];
    while ((size = bin.read(buf)) != -1) {
    len += size;
    out.write(buf, 0, size);
    // 控制台打印文件下载的百分比情况
    System.out.println("下载了-------> " + len * 100 / fileLength + "% ");
    }
    // 关闭资源
    bin.close();
    out.close();
    System.out.println("文件下载成功!");
    } catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    System.out.println("文件下载失败!");
    } finally {
    return file;
    }

    }

    /**
    * 测试
    *
    * @param args
    */
    public static void main(String[] args) {
    // 指定资源地址,下载文件测试
    downloadFile("http://www.gov.cn/zhengce/pdfFile/1970_PDF.pdf", "d:/myPdf");

    }
    }

    以上是转自https://blog.csdn.net/u010197393/article/details/80476512,不过我有个疑问
    HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;为什么可以转呢,抽象类可以转成子类?我们学习java基础的时候不是说过抽象类URLConnection转成子类的前提是urlConnection的实例必须是子类,可以查看了openConnect()方法返回的是一个抽象类
    是不是很奇怪?对这个问题我进行了源码深入.先从哪里看呢,根据 url.openConnection();我们先从URL开始看
    1.第一步查看URL类,点击url.openConnection方法里面调用的是 
    return handler.openConnection(this);
    
    那么这个hander是什么东西呢?我们该类里面有一个叫做URLStreamHandler handler的声明,最终调用的还是hander.openConnection(),不过这个hander那么多子类继承方法(如下图),具体要调用哪个子类呢?
    
    

    2.分析到这里,我们还是重点放在URL的构造方法上面

     public URL(String spec) throws MalformedURLException {
            this(null, spec);
        }
    

    this方法最后会调用哪些代码呢?看图

    看图可以说明,URL在初始化的时候应该就是根据我们初始化 URL url = new URL(urlPath);这个的时候判断是不是http,上图我打断点确实最后是http协议,然后hander会调用相应的子类,具体来说会调用sun.net.www.protocol.http的hander,是不是这样子呢?看下图就知道

    3.最后一步看清楚了,其实在上图就可以看出,会调用上图最后一个方法,返回的是HttpURLConnection的实例,所以真相大白了,url.openConnection()是根据url来决定是哪个子类的,该例子中传了‘http://www.gov.cn/zhengce/pdfFile/1970_PDF.pdf’,最后返回的是HttpURLConnection的子类。

    好了,是时候睡觉了


  • 相关阅读:
    简单说说 Java 的 JVM 内存结构
    cpu怎么实现运算的
    triplet
    LCT的一些坑【已经变成坑点集合了233】
    插头DP学习笔记
    一个坑-卡常
    NOIP2017游记
    洛谷P4015 运输问题
    线性基学习笔记
    洛谷P4331[BOI2004] sequence
  • 原文地址:https://www.cnblogs.com/imfjj/p/11233556.html
Copyright © 2020-2023  润新知