gpt4 book ai didi

java - 将 InputStream 写入文件的内存友好方式

转载 作者:行者123 更新时间:2023-12-02 08:53:09 26 4
gpt4 key购买 nike

我正在尝试编写一个图像批量下载器。从 URLConnection 获取 InputStream 非常简单,但下载所有文件需要一段时间。使用多线程确实可以加快速度,但是有很多线程下载文件可能会使用大量内存。这是我发现的:

inInputStreamfile 为目标 Filefos >FileOutputStream文件

简单的方法

fos.write(in.readAllBytes());

读取整个文件,写入返回的byte[]。可能可用于获取网站源代码,但不适用于较大的文件(例如图像)。

写入 block

 byte[] buffer = new byte[bufsize];
int read;
while ((read = in.read(buffer, 0, bufsize)) >= 0) {
fos.write(buffer, 0, read);
}

对我来说似乎更好。

in.transferTo(fos)

in.transferTo(fos);

在内部写入 block ,如上所示。

文件.copy()

Files.copy(in, file.toPath(),  StandardCopyOption.REPLACE_EXISTING);

似乎使用 native 实现。

当并行执行数十次时,我应该使用其中哪一项来最大限度地减少内存使用?

这是一个有趣的小项目,外部库对于我来说是多余的。另外,我无法使用 ImageIO,因为它无法处理 webms、一些 png/jpg 和动画 gif。

编辑:
这个问题是基于并发写入是可能的假设。然而,情况似乎并非如此。我可能会同时获取图像链接,然后依次下载它们。不管怎样,谢谢您的回答!

最佳答案

简短的答案是:从内存使用的角度来看,最好的解决方案是使用以 block 的形式读取和存储数据的版本。

缓冲区大小的选择基本上应考虑同时下载的数量、可用内存、下载速度以及目标驱动器在数据传输速率和 IOPS 方面的效率。

长的答案是文件的并发下载并不一定意味着下载会更快。实际加快整体下载时间的同时下载数量主要取决于:

  • 您要下载的主机数量
  • 您所在主机的互联网连接速度下载中,受本主机网卡速度限制
  • 您的互联网连接速度,受该主机网络适配器速度的限制
  • 您要从中下载的主机的存储 IOps
  • 您要下载到的存储空间的 IOps
  • 您从中下载的主机上的存储传输速率
  • 您下载到的存储空间的传输速率
  • 本地和远程主机的性能。例如,某些较旧或低成本的 Android 设备可能会受到 CPU 速度的限制。

例如,如果源主机具有单个硬盘驱动器并且单个连接已经提供了完整的连接速度,那么使用多个连接是没有用的,因为它会通过传输传输的切换开销而使下载速度变慢文件。

源主机也可能对单个连接有速度限制,因此多个连接可以加快速度。

HDD驱动器的IOPS值通常约为80 IOPS,传输速率约为80 MB/s,这些因素可能会限制下载/上传的速度。因此,实际上您无法每秒从此类磁盘写入或读取超过 80 个文件,并且无法超过 80MB/s 左右的传输限制,当然这几乎不取决于磁盘型号。

SSD 驱动器通常具有数万 IOPS 和 > 400 MB/s 的传输速率,因此限制要大得多,但对于真正快速的互联网连接,它们仍然很重要。

关于java - 将 InputStream 写入文件的内存友好方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60655845/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com