views:

112

answers:

3

Is there a native JDK code to copy files(buffers, streams, or whatever)?

+2  A: 

Your best option is to use Java NIO:

http://java.sun.com/javase/6/docs/api/java/nio/package-summary.html

For buffers see:

http://java.sun.com/javase/6/docs/api/java/nio/package-summary.html#buffers

For stream however, see the following article:

http://java.sun.com/docs/books/tutorial/essential/io/file.html#readStream

There are frameworks built on top of this, namely Mina and Netty:

Jon
Thanks! And add to your list the Apache Commons IO, its very good!
Tom Brito
+2  A: 

If by "native" you mean "part of the Java standard API" (rather than platform-dependant code, which is usually called "native" in the Java world) and by "copy files" you mean "single method that takes a file and a target path and produces a copy of the file's contents" then no, there is no such method in the standard API. You have to open an InputStream and an OutputStream (optionally get their more efficient FileChannels) and use a buffer to transfer bytes. Convenient single methods to call are found in Apache Commons IO.

Michael Borgwardt
Correct me if I'm wrong, but native in the Java world generally means platform dependent code...
Jon
nope, "native" in the java world mean its platform dependent code, aka the code is compiled and runs natively on the platform. While the standard API is platform independent and usually written in Java, that code will run as Byte Code in the JVM - in theory at least Byte Code is always the same no matter what platform you are in.
KingInk
@Jon, KingInk: *I* know that - but it suspect Tom does not.
Michael Borgwardt
Thanks @Michael! I just copied to my code the commons-io method that copy Streams.
Tom Brito
apache Commons IO is a bad choice, it doesn't use the NIO so it will be more CPU and memory intensive.
fuzzy lollipop
+2  A: 

This is the preferred way to copy a file since JDK 1.4 and later

public static void copyFile(final File sourceFile, final 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
    {
       source.close();
       destination.close();
    }
}

public abstract long transferFrom(ReadableByteChannel src, long position, long count) throws IOException

... This method is potentially much more efficient than a simple loop that reads from this channel and writes to the target channel. Many operating systems can transfer bytes directly from the filesystem cache to the target channel without actually copying them. ...

fuzzy lollipop
Are you really sure you don't need a loop? transferFrom() returns "The number of bytes, possibly zero, that were actually transferred", just like InputStream.read()
Michael Borgwardt
@Michael: Nope, the `source.size()` designates the number of bytes which needs to be transferred. @fuzzy: in this example, `destination` won't be closed when `source.close()` throws `IOException`.
BalusC
@BalusC Yeah, but the API doc explicitly says that the method may not, in fact, transfer that many bytes.
Michael Borgwardt
I have had the NIO file copy using channels running on Linux, Solaris and OSX in production environments for many years now and it has never failed to copy a file.
fuzzy lollipop
@Michael: I see. I'd rather stick to the 'good old' input/output loop.
BalusC
@fuzzy: Translation: "it works on my machines". Never depend on behaviour that the API does not guarantee.
Michael Borgwardt
Agree with @Michael. But still thanks @fuzzy! I can use this adding the loop part.
Tom Brito
The "loop part" is not needed and won't gain you anything. If it doesn't transfer the entire file looping won't do you any good. This method is not intended to be used in a loop. It is a "one shot" method, it either works or doesn't, which I have never had it fail.
fuzzy lollipop
search the internet, you won't find a single example of how to copy files using FileChannel that "loops" over transferTo/transferFrom. If they fail it is because the disk is full, the files get deleted out from under the code or some other catastrophic external event. "looping" over that is not what is intended nor useful and reduces the benefits of the methods as they are intended to be used.
fuzzy lollipop
No matter how much you say it works for you, don't change what the documentation says. It's your word against the documentation. Personally, I prefer to watch out with what documentation says, and you should too.
Tom Brito
point out where in the documentation it says to "loop" over transferFrom/transferTo, it says the exact OPPOSITE and I quoted that in my answer.
fuzzy lollipop