在Java中高效地从URL读取文件并转换为byte[]

6

我正在尝试寻找一种更高效的方法,从远程URL读取文件并将其保存到字节数组中。以下是我目前拥有的代码:

private byte[] fetchRemoteFile(String location) throws Exception {
  URL url = new URL(location);
  InputStream is = null;
  byte[] bytes = null;
  try {
    is = url.openStream ();
    bytes = IOUtils.toByteArray(is);
  } catch (IOException e) {
    //handle errors
  }
  finally {
    if (is != null) is.close();
  }
  return bytes;
}

正如你所看到的,我目前将URL传递给这个方法,在那里它使用InputStream对象读取文件的字节。该方法使用Apache Commons IOUtils。然而,这种方法调用往往需要相对较长的时间来运行。当一个接一个地检索数百、数千或数十万个文件时,它会变得非常缓慢。有没有办法可以改进这个方法,使其运行更高效?我考虑过多线程,但我希望把它作为最后的手段存下来。


没有多线程,你只能一个接一个地进行。 - Sotirios Delimanolis
代码没有问题(除了字节数组必须适合堆和固有的2GB限制之外,但我假设您也不介意)。感知到的“缓慢”可能来自于URL是http的,每个文件都需要建立一个新的网络连接来检索(如果有许多小文件,则开销很大)。除了使用多个请求(即多线程)直接使用http 1.1保持连接外,没有太多潜力可以加速此过程。 - Durandal
@Sotirios 是的,我在想是否有办法使上面的代码更高效,即使一个接一个地运行,也比现在快。我不知道除了多线程之外是否真的有什么我可以做的,但这就是我为什么会问的原因。 - DerStrom8
首先找出瓶颈在哪里。是网络慢还是服务器或其他原因。只有当你知道了这一点,才能考虑优化。例如,如果网络连接慢,多线程也无法带来好处。 - Henry
谢谢大家,这正是我倾向的方向。我仍在努力组织一些性能测试来确定哪些部分最慢,但只是想看看是否有明显的改进可以对我已经拥有的东西进行。非常感谢! - DerStrom8
1个回答

2

您的做法看起来完全没问题。

但是,如果您说:

"然而,这种方法调用往往需要相对较长的时间才能运行"

您可能会遇到以下问题:

  • 网络、连接问题

  • 您确定每个文件都在单独的线程中下载吗?

如果您正在使用多线程,请确保 VM args-XmsYYYYM-XmxYYYYM 配置正确,因为如果没有配置好,您可能会面临处理器未使用所有内核的问题。我曾经遇到过这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接