1


我想批量复制文件,最佳做法是什么?
例如我有:

LIst<String> pathesList ...
String dist = "c:/myfolder/";

简单的方法是循环抛出 pathesList 和每个路径副本到目标文件夹。
我的问题是如果有数百个文件并且每个文件都非常大,大约 50-100mb。
你能给我什么建议?
也许用多线程复制文件?
文件不在同一个文件夹中,所有文件的目的地都是一个文件夹。谢谢。

4

4 回答 4

6

复制文件几乎可以肯定是 IO 绑定的。加快速度的方法是使用支持更多 IOP 的磁盘子系统。例如,SSD 可以支持超过 1000 倍于 HDD 的 IOPS 数量。这不是您可以在软件中做得更快的事情,因为它不是瓶颈。

您可以采取一些技巧来加快磁盘访问速度,但操作系统可以为您完成其中大部分操作,例如在顺序读取和缓存文件写入时预取文件,而不是立即将它们提交到磁盘。

于 2013-08-20T08:42:52.280 回答
1

NIO 传输方法是处理大文件的最佳方法,但对于小文件(< 5 MB)它不是最快的。但是自定义缓冲区策略(以及 NIO 缓冲区)也是复制文件的快速方法。

我们还看到,对于大文件(< 1 GB),使用本机实用工具制作副本的方法比 NIO 更快,但对于小文件,由于调用外部程序的成本,它确实很慢。

所以也许,最好的方法是在小文件上制定自定义缓冲区策略,在大文件上制定 NIO 传输,也许在真正更大的文件上使用本机可执行文件。但在其他计算机和操作系统上进行测试也会很有趣。

我们可以从这个基准中得出几个规则:

  1. 从未逐字节(或逐字符)复制文件
  2. 比流中更喜欢您身边的缓冲区,以减少对 read 方法的调用,但不要忘记流中的缓冲区
  3. 注意缓冲区的大小
  4. 如果您只需要传输文件的内容,请不要使用字符转换,因此如果您只需要流,请不要使用 Reader。
  5. 不要犹豫使用通道进行文件传输,这是最快的文件传输方式。
  6. 仅考虑对真正更大的文件进行本机可执行调用。
  7. Java 7 的新 Path 方法真的很快,除了在两个磁盘之间传输一个巨大的文件。

有用的链接:巴蒂斯特博客

于 2013-08-20T08:58:35.770 回答
0

如果要将目录中的所有文件复制到另一个目录并且正在使用 Java 7,则可以使用 java.nio.file.Files 类的 copy() 方法。它使用文件系统提供程序来复制文件。因此,您不需要遍历一组文件,并且性能很高。

另一方面,如果您必须一个接一个地复制文件(Java 1.4+),您可以使用包 java.nio 中提供的功能,该包专为密集的 I/O 操作而设计。

// Getting file channels
 FileChannel in = new FileInputStream(source).getChannel();
 FileChannel out = new FileOutputStream(target).getChannel();

 // JavaVM does its best to do this as native I/O operations.
 in.transferTo(0, in.size(), out);

 // Closing file channels will close corresponding stream objects as well.
 out.close();
 in.close();
于 2013-08-20T09:09:07.723 回答
-3

使用线程池:

  1. 您可以使用线程池,您将在其中运行固定编号。线程复制文件。
  2. 每个线程将复制不同的文件。
  3. 一旦一个线程完成复制;下一个线程将来到池中继续复制下一个文件。

这样,性能不会降低,您将能够同时复制多个文件。

于 2013-08-20T08:32:44.353 回答