tags:

views:

9810

answers:

6

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?

+1  A: 

There could be something in Apache commons here, Specifically, the copyFile methods.

toolkit
+43  A: 

As toolkit mentions above, Apache Commons IO is the way to go, specifically FileUtils.copyFile(); it handles all the heavy lifting for you.

And as a postscript, note that the version of FileUtils currently in the subversion repository has added the use of NIO for copying files; NIO can significantly increase file-copying performance, in a large part because the NIO routines defer copying directly to the OS/filesystem rather than handle it by reading and writing bytes through the Java layer. So if you're looking for performance, it might be worth checking Commons IO out of the SVN repo rather than using the current 1.4 version.

delfuego
Very helpful - do you have any insight as to when an official release will incorporate these nio changes?
Pete
I have no clue... I've scoured every source of public info I can find, and there's no mention of a possible release date. The JIRA site shows only five open issues, though, so maybe soonish?
delfuego
This is very fast also, I replaced a section of code that we were executing xCopy to copy some directories and it has increased the speed very nicely. (I did use the repository version)
drye
Public release of Apache Commons IO still at 1.4, grrrrrrr
Pete
+25  A: 

I would avoid the use of a mega api like apache commons. This is a simplistic operation and its built into the JDK in the new NIO package. It was kind of already linked to in a previous answer, but the key method in the NIO api are the new functions "transferTo" and "transferFrom".

http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html#transferTo(long,%20long,%20java.nio.channels.WritableByteChannel)

One of the linked articles shows a great way on how to integrate this function into your code, using the transferFrom:

public static void copyFile(File sourceFile, File destFile) throws IOException {
 if(!destFile.exists()) {
  destFile.createNewFile();
 }

 FileChannel source = null;
 FileChannel destination = null;
 try {
  source = new FileInputStream(sourceFile).getChannel();
  destination = new FileOutputStream(destFile).getChannel();
  destination.transferFrom(source, 0, source.size());
 }
 finally {
  if(source != null) {
   source.close();
  }
  if(destination != null) {
   destination.close();
  }
}

Learning NIO can be a little tricky, so you might want to just trust in this mechanic before going off and trying to learn NIO overnight. From personal experience it can be a very hard thing to learn if you don't have the experience and were introduced to IO via the java.io streams.

Josh
Thanks, useful info. I would still argue for something like Apache Commons, especially if it uses nio (properly) underneath; but I agree it is important to understand the underlying fundamentals.
Pete
I agree it's important to understand the backgrounds of the nio but I still would go with the Jakarta Commons.
Ravi Wallau
+8  A: 

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!

brad
+4  A: 

Available as standard in 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

I can't believe it took them so long to standardise something so common and simple as file copying :(

Ryan
+2  A: 

Google's Guava library also has this:

http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/io/Files.html

Andrew McKinlay