在使用java nio读取的同一文件上打开FileOutputStream时发生FileNotFoundException

在使用java nio读取的同一文件上打开FileOutputStream时发生FileNotFoundException,java,nio,Java,Nio,我有一个文本编辑器,它使用与下面几乎相同的代码进行阅读和写作。当我打开小文件进行编辑时,当我再次尝试保存它们时,总是会出现此错误。但真正有趣的是,我的文本编辑器可以很好地处理大约600字节或更多的文件(每次似乎都会有所不同),而我在这里无法复制这种行为 我目前的解决方法是检查文件大小是否小于1024字节,如果是这样,则使用java.io import java.io.*; import java.nio.*; import java.nio.channels.*; import java.nio

我有一个文本编辑器,它使用与下面几乎相同的代码进行阅读和写作。当我打开小文件进行编辑时,当我再次尝试保存它们时,总是会出现此错误。但真正有趣的是,我的文本编辑器可以很好地处理大约600字节或更多的文件(每次似乎都会有所不同),而我在这里无法复制这种行为

我目前的解决方法是检查文件大小是否小于1024字节,如果是这样,则使用java.io

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();
        }
    }
}
对于上面的代码,对于从4字节到10kb的各种大小的test.txt,我都会遇到这个错误:

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)
java.io.FileNotFoundException:test.txt(请求的操作无法执行
在用户映射节打开的文件上进行rmed)
在java.io.FileOutputStream.open(本机方法)
位于java.io.FileOutputStream。(未知源)
位于java.io.FileOutputStream。(未知源)
at Test.main(Test.java:23)

有人能解释一下我做错了什么,以及我如何在仍然使用nio阅读的情况下使其工作吗?

您需要显式地取消映射使用
FileChannel.map(…)
调用映射的区域

map(…)
的Javadoc说明:

映射一旦建立,就不依赖于用于创建它的文件通道。特别是,关闭通道不会影响映射的有效性

告诉你取消映射缓冲区

但是,这里仍然有一个对MappedBybeBuffer.unmap方法的请求(从2002年开始)

它建议了一些变通方法,因此您可以尝试它们