在 Java 中复制文件的最快方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4004760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 08:12:29  来源:igfitidea点击:

Fastest way to copy files in Java

javafile-io

提问by Mato

What ist the fastest way to copy a big number of files in Java. So far I have used file streams and nio. Overall streams seem to be faster than nio. What experiences did you make so far?

在 Java 中复制大量文件的最快方法是什么。到目前为止,我已经使用过文件流和 nio。整体流似乎比 nio 快。到目前为止你有什么经验?

采纳答案by mihn

http://www.baptiste-wicht.com/2010/08/file-copy-in-java-benchmark/might get you your answer.

http://www.baptiste-wicht.com/2010/08/file-copy-in-java-benchmark/可能会给你答案。

For the benchmark, I made the tests using different files.

  1. Little file (5 KB)
  2. Medium file (50 KB)
  3. Big file (5 MB)
  4. Fat file (50 MB)
  5. And an enormous file (1.3 GB) only binary

And I made the tests first using text files and then using binary files. I made the tests using in three modes :

  1. On the same hard disk. It's an IDE Hard Disk of 250 GB with 8 MB of cache. It's formatted in Ext4.
  2. Between two disk. I used the first disk and an other SATA Hard Disk of 250 GB with 16 MB of cache. It's formatted in Ext4.
  3. Between two disk. I used the first disk and an other SATA Hard Disk of 1 TB with 32 MB of cache. It's formatted using NTFS.

I used a benchmark framework, described here, to make the tests of all the methods. The tests have been made on my personal computer (Ubuntu 10.04 64 bits, Intel Core 2 Duo 3.16 GHz, 6 Go DDR2, SATA Hard Disks). The Java version used is a Java 7 64 bits Virtual Machine...

对于基准测试,我使用不同的文件进行了测试。

  1. 小文件 (5 KB)
  2. 中等文件 (50 KB)
  3. 大文件 (5 MB)
  4. 胖文件 (50 MB)
  5. 和一个巨大的文件(1.3 GB)只有二进制

我首先使用文本文件进行测试,然后使用二进制文件。我使用三种模式进行了测试:

  1. 在同一个硬盘上。它是一个 250 GB 的 IDE 硬盘,带有 8 MB 的缓存。它的格式为 Ext4。
  2. 两盘之间。我使用了第一个磁盘和另一个 250 GB 的 SATA 硬盘,具有 16 MB 的缓存。它的格式为 Ext4。
  3. 两盘之间。我使用了第一个磁盘和另一个 1 TB 的 SATA 硬盘,具有 32 MB 的缓存。它是使用 NTFS 格式化的。

我使用了此处描述的基准框架来对所有方法进行测试。测试是在我的个人电脑上进行的(Ubuntu 10.04 64 位,Intel Core 2 Duo 3.16 GHz,6 Go DDR2,SATA 硬盘)。使用的 Java 版本是 Java 7 64 位虚拟机...

回答by Tony Ennis

Have java fork off an OS batch script that copies the files. Your code might have to write the batch script.

让 java fork 关闭复制文件的操作系统批处理脚本。您的代码可能必须编写批处理脚本。

回答by Romain Hippeau

I would use:

我会用:

import java.io.*;
import java.nio.channels.*;

public class FileUtils{
    public static void copyFile(File in, File out) 
        throws IOException 
    {
        FileChannel inChannel = new
            FileInputStream(in).getChannel();
        FileChannel outChannel = new
            FileOutputStream(out).getChannel();
        try {
            inChannel.transferTo(0, inChannel.size(),
                    outChannel);
        } 
        catch (IOException e) {
            throw e;
        }
        finally {
            if (inChannel != null) inChannel.close();
            if (outChannel != null) outChannel.close();
        }
    }

    public static void main(String args[]) throws IOException{
        FileUtils.copyFile(new File(args[0]),new File(args[1]));
  }
}

If any of your files are bigger than 64M in Windows you might need to look at this: http://forums.sun.com/thread.jspa?threadID=439695&messageID=2917510

如果您的任何文件在 Windows 中大于 64M,您可能需要查看:http: //forums.sun.com/thread.jspa?threadID=439695&messageID=2917510

回答by mcacorner

You can use either FileUtils implementation of apache commons-io library to copy file

您可以使用 apache commons-io 库的 FileUtils 实现来复制文件

FileUtils.copyFile(new File(sourcePath), new File(destPath));

Which uses FileChannelfor IO operation.

它使用FileChannel进行 IO 操作。

Or use java.nio.file.Files's copy()method.

或者使用 java.nio.file.Filescopy()方法。

回答by Raso

Its depend of files(bigger files), for me is fastest way this one with buffered stream

它依赖于文件(更大的文件),对我来说是带缓冲流的最快方法

 public void copyFile(File inFileStr, File outFileStr) throws IOException {

    try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inFileStr)); 
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFileStr))) {

        byte[] buffer = new byte[1024 * 1024];
        int read = 0;
        while ((read = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, read);
        }

        bis.close();
        bos.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }

}

回答by fuat

Using Stream

使用流

private static void copyFileUsingStream(File source, File dest) throws IOException {
    InputStream is = null;
    OutputStream os = null;
    try {
        is = new FileInputStream(source);
        os = new FileOutputStream(dest);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
    } finally {
        is.close();
        os.close();
    }
}

Using Channel

使用频道

private static void copyFileUsingChannel(File source, File dest) throws IOException {
    FileChannel sourceChannel = null;
    FileChannel destChannel = null;
    try {
        sourceChannel = new FileInputStream(source).getChannel();
        destChannel = new FileOutputStream(dest).getChannel();
        destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
       }finally{
           sourceChannel.close();
           destChannel.close();
       }
}

Using Apache Commons IO

使用 Apache Commons IO

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
    FileUtils.copyFile(source, dest);
}

Using Java SE 7 Files

使用 Java SE 7 文件

private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
    Files.copy(source.toPath(), dest.toPath());
}

Performance test

性能测试

File source = new File("/Users/tmp/source.avi");
File dest = new File("/Users/tmp/dest.avi");

//copy file conventional way using Stream
long start = System.nanoTime();
copyFileUsingStream(source, dest);
System.out.println("Time taken by Stream Copy = "+(System.nanoTime()-start));

//copy files using java.nio FileChannel
source = new File("/Users/tmp/sourceChannel.avi");
dest = new File("/Users/tmp/destChannel.avi");
start = System.nanoTime();
copyFileUsingChannel(source, dest);
System.out.println("Time taken by Channel Copy = "+(System.nanoTime()-start));

//copy files using apache commons io
source = new File("/Users/tmp/sourceApache.avi");
dest = new File("/Users/tmp/destApache.avi");
start = System.nanoTime();
copyFileUsingApacheCommonsIO(source, dest);
System.out.println("Time taken by Apache Commons IO Copy = "+(System.nanoTime()-start));

//using Java 7 Files class
source = new File("/Users/tmp/sourceJava7.avi");
dest = new File("/Users/tmp/destJava7.avi");
start = System.nanoTime();
copyFileUsingJava7Files(source, dest);
System.out.println("Time taken by Java7 Files Copy = "+(System.nanoTime()-start));

RESULTS

结果

Time taken by Stream Copy            =  44,582,575,000
Time taken by Java7 Files Copy       =  89,061,578,000
Time taken by Channel Copy           = 104,138,195,000
Time taken by Apache Commons IO Copy = 108,396,714,000