How to unmap a file from memory mapped using FileChannel in java?

learner135 picture learner135 · Jun 4, 2010 · Viewed 27.6k times · Source

I am mapping a file("sample.txt") to memory using FileChannel.map() and then closing the channel using fc.close(). After this when I write to the file using FileOutputStream, I am getting the following error:

java.io.FileNotFoundException: sample.txt (The requested operation cannot be per formed on a file with a user-mapped section open)

File f = new File("sample.txt");
RandomAccessFile raf = new RandomAccessFile(f,"rw");
FileChannel fc = raf.getChannel();
MappedByteBuffer mbf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
fc.close();
raf.close();

FileOutputStream fos = new FileOutputStream(f);
fos.write(str.getBytes());
fos.close();

I presume this may be due to file being still mapped to the memory even after I close the FileChannel. Am I right?. If so, how can I "unmap" the file from memory?(I can't find any methods for this in the API). Thanks.

Edit: Looks like it(adding an unmap method) was submitted as RFE to sun some time back: http://bugs.sun.com/view_bug.do?bug_id=4724038

Answer

Timur Yusupov picture Timur Yusupov · Feb 18, 2011

Following static method could be used:

public static void unmap(MappedByteBuffer buffer)
{
   sun.misc.Cleaner cleaner = ((DirectBuffer) buffer).cleaner();
   cleaner.clean();
}

But this is unsafe solution because of following:
1) Lead to failures if someone use MappedByteBuffer after unmap
2) It relies on MappedByteBuffer implementation details