无法从新锁定的文件中读取

时间:2011-06-14 14:27:35

标签: java filelock

所以我尝试锁定文件来读取它,但是我得到IOException,知道为什么?

public static void main(String[] args){
    File file = new File("C:\\dev\\harry\\data.txt");

    FileReader fileReader = null;
    BufferedReader bufferedReader = null;
    FileChannel channel = null;
    FileLock lock = null;
    try{
        channel  = new RandomAccessFile(file, "rw").getChannel();
        lock = channel.lock();
        fileReader = new FileReader(file);
        bufferedReader = new BufferedReader(fileReader);
        String data;
        while((data = bufferedReader.readLine()) != null){
            System.out.println(data);
        }
    }catch(IOException e){
        e.printStackTrace();
    }finally{
        try {
            lock.release();
            channel.close();
            if(bufferedReader != null) bufferedReader.close();
            if(fileReader != null) fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我收到此错误IOException: The process cannot access the file because another process has locked a portion of the file

3 个答案:

答案 0 :(得分:3)

也可以将其添加为答案而不是评论。

如果您使用FileLock API,则需要使用相应的NIO文件apis。

答案 1 :(得分:1)

here (in case it gets deleted)再现我的回答,并添加Jeff Foster的反馈:

考虑到抛出OverlappingFileLockException异常的实例,似乎同一进程中的另一个线程试图锁定同一个文件。这不是A和B之间的冲突,而是B中的冲突,如果有人通过lock()方法的API文档以及它抛出OverlappingFileLockException的条件:

  

如果锁定与请求重叠   这个Java已经拥有了这个区域   虚拟机,或者如果是另一个线程   已经在此方法中被阻止了   试图锁定重叠   同一文件的区域

防止这种情况的唯一解决方案是阻止B中的任何其他线程获取同一文件或文件中相同重叠区域的锁定。

被抛出的IOException有一些更有趣的消息。它可能证实了上述理论,但没有查看整个源代码,我无法确认。预期lock方法将被阻止,直到获得独占锁。如果它被获得,那么从文件中读取应该没有问题。除了一个条件。如果文件已被同一JVM在不同的线程中打开(并锁定),使用File对象(或换句话说,第二个/不同的文件描述符),则对第一个文件描述符的尝试读取将失败如果获得了锁(毕竟锁没有锁定其他线程)。

<击> 一种改进的设计,就是在每个进程中有一个单独的线程获取文件的独占锁(当使用单个File对象或单个文件描述符)仅一段时间时,执行所需的活动。文件,然后释放锁。

正如Jeff指出的那样,使用NIO API可能会解决问题。这完全是由于 FileReader API打开新文件描述符 的可能性,这与获取锁定的文件不同。

答案 2 :(得分:0)

也许你想要的更像是:

FileInputStream fis = new FileInputStream(file);
channel = fis.getChannel();
channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(fis));