【问题标题】:Download Multiple Files in Java在 Java 中下载多个文件
【发布时间】:2017-05-04 18:44:45
【问题描述】:

我有一个程序需要从网页下载小文本文件,为此我编写了以下代码:

URLConnection connection = null;    // Connection to the URL data
InputStreamReader iSR = null;       // Stream of the URL data
BufferedReader bR = null;           // Reader of URL data
URL url = null;                     // URL based on the specified link

// Open the connection to the URL web page
url = new URL(urlLink);
connection = url.openConnection();

// Initialize the Readers
iSR = new InputStreamReader(connection.getInputStream());
bR = new BufferedReader(iSR);

// Fetch all of the lines from the buffered reader and join them all
// together into a single string.
return bR.lines().collect(Collectors.joining("\n"));

不幸的是,我从中下载数据的服务器的 TTFB 等待时间很长。根据开发者工具 (F12),大约 90% 的总下载时间是 TTFB。如果我要下载大量文件,这会使我的 Java 程序下载速度非常慢。基本上,对于每个文件,我们打开一个连接,等待 250 毫秒,下载,打开一个连接,再等待 250 毫秒,下载,这对于大量文件来说非常慢。我能够使用线程来减少问题,因此我有大约 10 个线程,每个线程下载我需要的所有文件的一部分。这加快了我的程序,但它并没有解决我遇到的根本问题。每个线程仍然需要打开一个连接,等待 250 毫秒,下载,然后重复。我理想的解决方案是以某种方式同时发送所有请求并等待 250 毫秒让 TTFB 时间完成,然后从网页中单独下载所有数据。我能想到的唯一方法是创建 1000 个线程并在每个线程上打开一个 URL 连接,但这似乎是一种非常糟糕的方法。有没有其他方法可以打开多个 URL 连接并让 TTFB 期间同时发生?

【问题讨论】:

    标签: java multithreading download


    【解决方案1】:

    我认为你是在正确的轨道上。启动多个线程以减少总 TTFB 等待时间听起来是个好主意。为了避免启动过多的线程,您可以考虑使用Object Pool Pattern 之类的设计模式将同时处于活动状态的线程数量限制为一定数量。

    【讨论】:

    • 尽管多线程绝对是要走的路,但由于多线程的异步特性而不是逐个获取文件,您需要考虑处理和从潜在异常中恢复的需要一。例如,您可以拥有TODO 文件的“同步”集合,每个线程将在成功完成后从另一个集合中读取并放入另一个集合,或者在失败时将项目返回到TODO 集合(您还可以包括重试计数等.)。毕竟这一切都取决于您的要求。
    【解决方案2】:

    1000 个线程将消耗 500-1000 MB 的核心内存。这是这种方法的唯一缺点。如果您的计算机有足够的内存,这是最简单、最可靠的解决方案。 如果您不想花费太多内存(特别是如果您想要更多同时连接),那么您可以使用 Java NIO API。它有 2 种口味,Nio1 和 Nio2。 Nio1 过于复杂,无法直接使用,但有许多包装库,例如网状。 Nio2 可以直接使用。无论哪种情况,您都可以显着减少内存消耗并保持合理数量的工作线程(例如,等于处理器内核的数量)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 2016-06-22
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多