tags:

views:

397

answers:

2

I have a text editor that uses code almost identical to the below for reading and writing. When I open small files for editting, I always get this error when I try to save them again. The really interesting thing though is that my text editor works fine for files with about 600 bytes or more (seems to vary each time), behaviour that I haven't been able to replicate here.

My current workaround is to check for file size < 1024 bytes, and use java.io if that's the case.

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;

public class Test {
    public static void main(String[] args) {
        String text = null;
        try {
            FileInputStream fis = new FileInputStream("test.txt");
            FileChannel ifc = fis.getChannel();
            CharBuffer cb = Charset.forName("ISO-8859-15").newDecoder().
                    decode(ifc.map(FileChannel.MapMode.READ_ONLY, 0,
                    (int) ifc.size()));
            text = cb.toString();
            ifc.close();
            fis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        try {
            FileOutputStream fos = new FileOutputStream("test.txt");
            OutputStreamWriter osw = new OutputStreamWriter(
                    fos, "ISO-8859-15");
            osw.write(text);
            osw.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

For the above code, I get this error for various sizes of test.txt from 4 bytes to 10kb:

java.io.FileNotFoundException: test.txt (The requested operation cannot be perfo
rmed on a file with a user-mapped section open)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at java.io.FileOutputStream.<init>(Unknown Source)
        at Test.main(Test.java:23)

Can anyone explain what I'm doing wrong and how I can get this to work while still reading with nio?

A: 

You need to explicitly unmap the region that you mapped with the FileChannel.map(...) call.

The Javadoc for map(...) says this:

A mapping, once established, is not dependent upon the file channel that was used to create it. Closing the channel, in particular, has no effect upon the validity of the mapping.

Stephen C
+2  A: 

Stephen C told you to unmap the buffer.

However, here is a link to STILL OPEN ( from 2002 ) request for MappedBybeBuffer.unmap method.

It has a few workarounds suggested, so you may try them.

Alexander Pogrebnyak