3

I am writing a program that has to copy a sizeable, but not huge amount of data from folder to folder (in the range of several dozen photos at once). Originally I was using java.io.FileOutputStream to simply read to buffer and write out, but then I heard about potential performance increases using java.nio.FileChannel.

I don't have the resources to run a serious, controlled test with the data I have, but there seems to be no consensus on what the advantages of each are (other than FileChannel being thread safe). Some users report FileChannel being great for smaller files, others report huge speed increases with larger files.

I am wondering if anyone knows exactly what the intent of creating FileChannel was in the first place: was it designed for better performance? In what cases? And is there a definitive performance increase for general kinds of data, or are the differences I should expect to see trivial because I am not working with data that is specialized enough?

EDIT: Assume my data does not need to be thread safe.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
donnyton
  • 5,874
  • 9
  • 42
  • 60
  • Somewhat duplicate - http://stackoverflow.com/questions/106770/standard-concise-way-to-copy-a-file-in-java. – mindas Jul 05 '11 at 21:40
  • Yes, similar questions have been asked many times, but I am well aware of the advanced IO packages out there. I am more concerned right now with a raw performance comparison of each. – donnyton Jul 06 '11 at 02:08

3 Answers3

2

FileChannel.transferFrom/To should be faster than IO stream for file copying.

Or you can simply use Java 7's java.nio.file.Files.copy(source, target). That should be as fast as it can get.

However, in the end, performance won't be noticeably different - hard disk speed is the bottleneck.


FileChannel is not non-blocking, and it is not selectable. Not sure if they are going to add these features in future. Java 7 has AsynchronousFileChannel though.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • I wanted to add that, depending on implementation, a `transferXXX()` operation can be a lot faster because the data isn't copied between kernel and user-space in memory. – erickson Jul 05 '11 at 21:31
  • It should be, as it claimed - it would be a shame if this API is not at least not slower than stream API. Yet shame it is, many people report it is indeed slower in many situations. – irreputable Jul 05 '11 at 21:45
1

Input and Output Streams assume a stream styled access to the file or resource. There are a few extra items which help (array reads) but the basic idea is that of a stream where you read in one or more characters at a time (possibly blocking until you have more characters available).

Channels are the means to copy information into Buffers. This provides a lower level of access to input and output routines. With thoughtful buffer sizing, the speed-ups can be impressive. Structuring your code around buffers can reduce the time spent in a read loop (also increasing performance). Finally, while it is possible to do pre-checking of input stream state in an attempt to avoid blocking, Channels and Buffers allow operations to perform in a non-blocking manner (even in the worst conditions).

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
0

Have you take a look at commons-io?

FileUtils.copyFileToDirectory(srcFile, destDir);
Thor
  • 6,607
  • 13
  • 62
  • 96
  • I have no real need for that much IO functionality. This is not an IO heavy program, there is just one operation once in a while that happens to copy lots of files and needs to be fast. – donnyton Jul 05 '11 at 20:39
  • That's why I mentioned it. IO performance depends a lot from the buffering strategy. The library is available for years, with continuous updates and lots of programming hours spent to it. I assume it performs better than own implementations, even when a certain amount is spent to it. – Thor Jul 05 '11 at 20:59