【问题标题】:Slow Download of some Links running HTTPUrlConnection in Java在 Java 中运行 HTTPUrlConnection 的一些链接下载缓慢
【发布时间】:2020-10-02 12:58:48
【问题描述】:

我是编程新手。我正在尝试编写一个适用于 Android 的应用程序,它下载带有 HTML 链接的列表并使用给定的链接来下载这些链接的内容。我将发布下载器的代码和日志。我的问题是:为什么有些链接需要大约 5 秒,而有些则需要 5 分钟?这不可能是网站的原因,因为当我在 Chrome 或其他浏览器中打开链接时,页面会立即加载。你们能帮帮我吗?

package com.example.newsreader;

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MyRunnable implements Runnable {

    String result = "";
    String urlSource="";

    public MyRunnable(String urlSource){
        this.urlSource = urlSource;
    }

    @Override
    public void run() {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    result = "";
                    URL url = new URL(urlSource);
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    urlConnection.setRequestMethod("GET");
                    InputStream inputStream = urlConnection.getInputStream();
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

                    int data = inputStreamReader.read();

                    while (data !=-1) {
                        char current = (char) data;
                        result += current;
                        data = inputStreamReader.read();
                    }

                    inputStream.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        try{
            t1.join();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public String getResult(){
        return result;
    }
}

日志数据: Times for Each Link to finish

【问题讨论】:

    标签: java android httpurlconnection runnable


    【解决方案1】:

    你是一个一个的读取数据,效率不高。相反,您应该创建 char 缓冲区并按小块读取数据。

    也不要连接很多字符串,使用StringBuilder,这样的事情使用更少的内存。

     public class MyRunnable implements Runnable {
    
        private final StringBuilder result = new StringBuilder();
        String urlSource="";
        private final char[] buffer = new char[512]; //allocating buffer
    
        public MyRunnable(String urlSource){
            this.urlSource = urlSource;
        }
    
        @Override
        public void run() {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        result.setLength(0); //clearing StringBuilder
                        URL url = new URL(urlSource);
                        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                        urlConnection.setRequestMethod("GET");
                        InputStream inputStream = urlConnection.getInputStream();
                        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                        
                        // now reading not by 1 char, but by 512 for once
                        int i;
                        while ((i = inputStreamReader.read(buffer)) != -1) {
                           result.append(buffer, 0, i);
                        }
    
                        inputStreamReader.close(); //close reader instead of InputStream
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            t1.start();
            try{
                t1.join();
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    
        public String getResult(){
            return result.toString(); //converting StringBuilder to String
        }
    }
    

    并且使用BufferedInputStream,它也提高了速度。

    InputStreamReader inputStreamReader = new InputStreamReader(new BufferedInputStream(inputStream));
    

    一些使用“https://www.google.com”的测试:

    Simple run
    time: 838 ms
    run with char buffer
    time: 264 ms
    Run with char buffer and BufferedInputStream
    time: 130 ms
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多