java - 在 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: 每个链接完成的时间
解决方案
您正在逐一读取数据,效率不高。相反,您应该创建 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
推荐阅读
- reactive-programming - 使用响应式 Couchbase java 驱动程序进行批处理
- list - 如何在 React Native 中的 FlatList 项上添加 Click 事件?
- visual-studio-code - Jest Puppeteer - 为其设置 Visual Studio 代码
- xml - Xml 下面的 Key 是什么?
- excel - 获取所有匹配值并根据另一列中第一次出现的值按顺序返回所有匹配项的公式
- flask - 将 power bi 仪表板嵌入到 Flask 应用程序中
- css - 部署到 Heroku 后 CSS 显示错误
- python - 如何在 time.sleep() 之后打印没有换行符
- python - python中的修剪平均值计算
- amazon-web-services - 如何在 Spinnaker 上配置 S3 存储