【问题标题】:Slow download with HttpURLConnection使用 HttpURLConnection 缓慢下载
【发布时间】:2014-05-14 15:26:19
【问题描述】:

我正在尝试制作一种下载网页的方法。 首先,我创建一个 HttpURLConnection。 其次,我调用 connect() 方法。 第三,我通过 BufferedReader 读取数据。

问题在于,对于某些页面,我可以获得合理的阅读时间,但对于某些页面,它非常慢(可能需要大约 10 分钟!)。慢页面总是相同的,它们来自同一个网站。使用浏览器打开这些页面只需几秒钟而不是 10 分钟。这是代码

static private String getWebPage(PageNode pagenode)
{
    String result;
    String inputLine;
    URI url;
    int cicliLettura=0;
    long startTime=0, endTime, openConnTime=0,connTime=0, readTime=0;
    try
    {
        if(Core.logGetWebPage())
            startTime=System.nanoTime();
        result="";
        url=pagenode.getUri();
        if(Core.logGetWebPage())
            openConnTime=System.nanoTime();
        HttpURLConnection yc = (HttpURLConnection) url.toURL().openConnection();
        if(url.toURL().getProtocol().equalsIgnoreCase("https"))
            yc=(HttpsURLConnection)yc;
        yc.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB;     rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)"); 
        yc.connect();
        if(Core.logGetWebPage())
            connTime=System.nanoTime();
        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));

        while ((inputLine = in.readLine()) != null)
        {
            result=result+inputLine+"\n";
            cicliLettura++;
        }
        if(Core.logGetWebPage())
            readTime=System.nanoTime();
        in.close();
        yc.disconnect();
        if(Core.logGetWebPage())
        {
            endTime=System.nanoTime();
            System.out.println(/*result+*/"getWebPage eseguito in "+(endTime-startTime)/1000000+" ms. Size: "+result.length()+" Response Code="+yc.getResponseCode()+" Protocollo="+url.toURL().getProtocol()+" openConnTime: "+(openConnTime-startTime)/1000000+" connTime:"+(connTime-openConnTime)/1000000+" readTime:"+(readTime-connTime)/1000000+" cicliLettura="+cicliLettura);
        }
        return result;
    }catch(IOException e){
        System.out.println("Eccezione: "+e.toString());
        e.printStackTrace();  
        return null;
    }
}

这里有两个日志样本 “正常”页面之一 getWebPage 执行大小:48261 响应代码=200 协议=http openConnTime:0 connTime:1 readTime:569 cicliLettura=359

“慢”页面之一http://ricette.giallozafferano.it/Pan-di-spagna-al-cacao.html/allcomments 看起来像这样 getWebPage 执行大小:1748261 响应代码=200 协议=http openConnTime:0 connTime:1 readTime:596834 cicliLettura=35685

【问题讨论】:

    标签: java html download


    【解决方案1】:

    您在这里看到的可能是您整理result 的方式的结果。请记住,Java 中的Strings 是不可变的——因此,当发生字符串连接时,必须实例化一个新的String,这通常涉及复制该String 中包含的所有数据。您为每一行执行以下代码:

    result=result+inputLine+"\n";
    

    在幕后,这行涉及:

    1. 创建了一个新的 StringBuffer,其中包含到目前为止 result 的全部内容
    2. inputLine 附加到 StringBuffer
    3. StringBuffer 转换为 String
    4. 为该String 创建一个新的StringBuffer
    5. 一个换行符附加到StringBuffer
    6. StringBuffer 转换为 String
    7. String 存储为 result

    随着result 变得越来越大,此操作将变得越来越耗时 - 您的结果似乎显示(尽管来自 2 个样本!)结果随着页面大小而急剧增加。

    改为直接使用StringBuffer

    StringBuffer buffer = new StringBuffer();
    while ((inputLine = in.readLine()) != null)
    {
        buffer.append(inputLine).append('\n');
        cicliLettura++;
    }
    String result = buffer.toString();
    

    【讨论】:

    • 简直太棒了,非常专业的答案。你能发一份解释文件吗?这是该页面的新输出: getWebPage Size: 1709466 Response Code=200 Protocollo=http openConnTime: 0 connTime:0 readTime:2257 cicliLettura=35686
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    相关资源
    最近更新 更多