一直困扰我的是,在Java中复制文件的唯一方法包括打开流,声明缓冲区,读入一个文件,循环遍历它,并将其写入到另一个steam。网络上充斥着类似的,但仍然略有不同的这类解决方案的实现。

是否有一种更好的方法能够保持在Java语言的范围内(即不涉及执行特定于操作系统的命令)?也许在一些可靠的开源实用程序包中,它至少会模糊这个底层实现,并提供一行解决方案?


当前回答

谷歌的Guava库也有一个复制方法:

公共静态无效复制(文件从, 文件) 抛出IOException 将所有字节从一个文件复制到另一个文件。

警告:如果to表示已存在的文件,则该文件 将被from的内容覆盖。如果是和 从引用同一个文件,该文件的内容 将被删除。 参数:从-源文件到-目标文件 抛出: IOException -如果发生I/O错误 IllegalArgumentException - if from.equals(to)

其他回答

public static void copyFile(File src, File dst) throws IOException
{
    long p = 0, dp, size;
    FileChannel in = null, out = null;

    try
    {
        if (!dst.exists()) dst.createNewFile();

        in = new FileInputStream(src).getChannel();
        out = new FileOutputStream(dst).getChannel();
        size = in.size();

        while ((dp = out.transferFrom(in, p, size)) > 0)
        {
            p += dp;
        }
    }
    finally {
        try
        {
            if (out != null) out.close();
        }
        finally {
            if (in != null) in.close();
        }
    }
}

上述代码有三个可能的问题:

如果getChannel抛出异常,则可能泄漏一个开放流。 对于大文件,您可能会尝试一次传输超出操作系统处理能力的文件。 您忽略了transferFrom的返回值,因此它可能只是复制文件的一部分。

这就是为什么org.apache.tools.ant.util.ResourceUtils.copyResource如此复杂。还要注意,虽然transferFrom没问题,但transferTo会在Linux上的JDK 1.4上中断(参见Bug ID:5056395)

谷歌的Guava库也有一个复制方法:

公共静态无效复制(文件从, 文件) 抛出IOException 将所有字节从一个文件复制到另一个文件。

警告:如果to表示已存在的文件,则该文件 将被from的内容覆盖。如果是和 从引用同一个文件,该文件的内容 将被删除。 参数:从-源文件到-目标文件 抛出: IOException -如果发生I/O错误 IllegalArgumentException - if from.equals(to)

在Java 7中作为标准提供,path.copyTo: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/Path.html http://java.sun.com/docs/books/tutorial/essential/io/copy.html

我不敢相信他们花了这么长时间来标准化像文件复制这样常见而简单的事情:(

这里有三种方法,您可以轻松地复制文件与一行代码!

Java7:

java.nio.file.Files #副本

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

公共汽车共享10:

文件实用程序#复制文件

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

番石榴:

文件#复制

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