Java - 最佳实践 - 如何批量复制多个文件?

时间:2013-08-20 08:25:58

标签: java multithreading io


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

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

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

4 个答案:

答案 0 :(得分:4)

复制文件几乎肯定是IO绑定的。提高速度的方法是使用支持更多IOP的磁盘子系统。例如SSD可以支持超过1000倍的IOPS作为HDD。这不是你可以在软件中更快地制作的东西,因为它不是瓶颈。

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

答案 1 :(得分:1)

NIO Transfer方法对于大文件来说是最好的方法,但它对于小文件来说并不是最快的(<5 MB)。但是自定义缓冲区策略(以及NIO缓冲区)也是复制文件的快速方法。

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

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

我们可以从这个基准中采取一些规则:

  1. 从未按字节(或char by char)
  2. 制作文件副本
  3. 优先选择一个缓冲区,而不是流中的缓冲区,以减少对read方法的调用,但不要忘记流中的缓冲区
  4. 注意缓冲区的大小
  5. 如果您只需要传输文件内容,请不要使用字符转换,因此如果只需要流,请不要使用Reader。
  6. 不要犹豫使用频道进行文件传输,这是进行文件传输的最快方式。
  7. 仅针对非常大的文件考虑本机可执行文件调用。
  8. 除了在两个磁盘之间传输大量文件外,Java 7的新Path方法非常快。
  9. 有用的链接:Baptiste blog

答案 2 :(得分:0)

如果要将目录中的所有文件复制到antoher目录并且正在使用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();

答案 3 :(得分:-3)

使用线程池:

  1. 您可以使用线程池,您将在其中运行固定号码。线程来复制文件。
  2. 每个帖子都会复制一个不同的文件。
  3. 一线完成复制;下一个线程将进入池继续复制下一个文件。
  4. 通过这种方式,性能不会降低,您可以同时复制多个文件。