Java中运行HTTPUrlConnection的某些链接的下载缓慢

问题描述

我是编程新手。我正在尝试为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;
    }
}

LOGDATA: Times for Each Link to finish

解决方法

您正在逐一读取数据,效率不高。相反,您应该创建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,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