Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error with NIO while trying to copy large file

Tags:

java

nio

I have the code to copy a file to another location.

public static void copyFile(String sourceDest, String newDest) throws IOException {

    File sourceFile = new File(sourceDest);
    File destFile = new File(newDest);
    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();
        }
    }

}
}

While copying small chunks, say, 300-400 Mb, everything works like magic. But when I tried to copy a file a size of 1.5 Gb it failed. The stack is:

run: 12.01.2011 11:16:36 FileCopier main SEVERE: Exception occured while copying file. Try again. java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:748) at sun.nio.ch.FileChannelImpl.transferFromFileChannel(FileChannelImpl.java:527) at sun.nio.ch.FileChannelImpl.transferFrom(FileChannelImpl.java:590) at FileCopier.copyFile(FileCopier.java:64) at FileCopier.main(FileCopier.java:27) Caused by: java.lang.OutOfMemoryError: Map failed at sun.nio.ch.FileChannelImpl.map0(Native Method) at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:745) ... 4 more BUILD SUCCESSFUL (total time: 0 seconds)

I haven't worked with NIO closely. Could you please help me out? Thank you so much in advance.

like image 271
Anton K. Avatar asked Jan 12 '11 08:01

Anton K.


1 Answers

I think you might have been hit by an old bug which already encountered some time ago. I was not trying to copy a file but rather to seek through an memory-mapped file which failed as well. For me the workaround is to seek through the file in a loop and request the GC and finalizers to run every now and then.

The memory-mapped ByteBuffers release their mapping in the finalizer and make room for new mappings. This is very ugly, but at least it works. Let's hope they did something about this in the coming NIO iteration.

like image 176
Waldheinz Avatar answered Sep 24 '22 19:09

Waldheinz