Standard concise way to copy a file in Java?

2018-12-31 02:15发布

It has always bothered me that the only way to copy a file in Java involves opening streams, declaring a buffer, reading in one file, looping through it, and writing it out to the other steam. The web is littered with similar, yet still slightly different implementations of this type of solution.

Is there a better way that stays within the bounds of the Java language (meaning does not involve exec-ing OS specific commands)? Perhaps in some reliable open source utility package, that would at least obscure this underlying implementation and provide a one line solution?

标签: java file copy
16条回答
人气声优
2楼-- · 2018-12-31 03:07

Three possible problems with the above code:

  1. If getChannel throws an exception, you might leak an open stream.
  2. For large files, you might be trying to transfer more at once than the OS can handle.
  3. You are ignoring the return value of transferFrom, so it might be copying just part of the file.

This is why org.apache.tools.ant.util.ResourceUtils.copyResource is so complicated. Also note that while transferFrom is OK, transferTo breaks on JDK 1.4 on Linux (see Bug ID:5056395) – Jesse Glick Jan

查看更多
流年柔荑漫光年
3楼-- · 2018-12-31 03:09

Note that all of these mechanisms only copy the contents of the file, not the metadata such as permissions. So if you were to copy or move an executable .sh file on linux the new file would not be executable.

In order to truly a copy or move a file, ie to get the same result as copying from a command line, you actually need to use a native tool. Either a shell script or JNI.

Apparently, this might be fixed in java 7 - http://today.java.net/pub/a/today/2008/07/03/jsr-203-new-file-apis.html. Fingers crossed!

查看更多
看风景的人
4楼-- · 2018-12-31 03:09

If you are in a web application which already uses Spring and if you do not want to include Apache Commons IO for simple file copying, you can use FileCopyUtils of the Spring framework.

查看更多
ら面具成の殇う
5楼-- · 2018-12-31 03:17

Now with Java 7, you can use the following try-with-resource syntax:

public static void copyFile( File from, File to ) throws IOException {

    if ( !to.exists() ) { to.createNewFile(); }

    try (
        FileChannel in = new FileInputStream( from ).getChannel();
        FileChannel out = new FileOutputStream( to ).getChannel() ) {

        out.transferFrom( in, 0, in.size() );
    }
}

Or, better yet, this can also be accomplished using the new Files class introduced in Java 7:

public static void copyFile( File from, File to ) throws IOException {
    Files.copy( from.toPath(), to.toPath() );
}

Pretty snazzy, eh?

查看更多
登录 后发表回答