File Copying Using the RandomAccessFile


The byte array is the computer's fundamental data structure. A disk file, for example, is a byte array if the file is not fragmented. Manipulating byte arrays is something that all computers do very well. Any computer smarter than the one in my wrist watch will be able to move byte arrays from one RAM location to another and from RAM to disk and back with minimal overhead. The java.io class that exactly maps to the computer's view is the RandomAccessFile — really just a byte array on disk.

  Not surprisingly, the RandomAccessFile is brilliantly fast. The image on the left shows the little file Create and Copy utility that I wrote for this article. It creates a 5MB test file (ASCII text) in 610 milliseconds. Then it makes a copy, reading the file in 437 millis and writing the copy file in 360 millis. (Test machine: Athlon 1600+, 40GB disk and 512MB RAM.)

This utility is not applet material as it reads from and writes to the local disk. To try it, you'll have to download it from my site and recompile to run on your machine.

Again, that's for a five megabyte file. I've christened my I/O method the "big gulp" method. You simply create a byte array as large as the entire file and then read or write in one command.

The File Creation Code

In the following code the variable "file" is a File holding the pathname chosen by the user and "gibberish" is the byte array holding the computer-generated nonsense text. It could hardly be simpler.

            RandomAccessFile raf = new RandomAccessFile( file, "rw" );
            raf.setLength( 0 );  // truncate, if it exists

            raf.write( gibberish );
            raf.close();
(This code is in a try block. A catch block writes some error output if there are any disk I/O problems.)

The File Copy Code

Again, the big gulp makes this file operation trivially simple.


            // open RandomAccessFiles
                RandomAccessFile sourceRaf = new RandomAccessFile( sourceFile, "r" );
                RandomAccessFile destRaf = new RandomAccessFile( destFile, "rw" );

            // truncate dest, if it exists
                destRaf.setLength( 0 );

            // make a byte buffer as long as the source
                byte[] buf = new byte[ (int) sourceFile.length() ];

            // do the copy
                sourceRaf.read( buf );
                destRaf.write( buf );

            // close 'em
                sourceRaf.close();
                destRaf.close();

(Like all disk I/O code, this is in a try block with an associated catch that reports any I/O errors.)

The only wrinkle here is that the RandomAccessFile's length() method returns a long which must be cast to an int to create the buffer. (If you forget this — as I always do — your compiler will tell you that you can't create a new byte array with a long.) By 2010 or so we'll have to think about multi-gigabyte arrays. For now, casting to an int is adequate.

The source for this file is FileCopy.java in the "articles" package. It's available free for non-commercial use at www.MartinRinehart.com. Look into the javasrc, click the "articles" package and then choose "FileCopy".

© August, 2005 by Martin Rinehart


java consultant home page icon

Back to Articles