Невозможно прочитать из недавно заблокированного файла - PullRequest
0 голосов
/ 14 июня 2011

Итак, я пытаюсь заблокировать файл, чтобы прочитать его, но я получил 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 ]

3 голосов
/ 14 июня 2011

Можно также добавить это как ответ вместо комментария.

Если вы используете FileLock API, вам нужно использовать соответствующий файл NIO apis.

1 голос
/ 14 июня 2011

Воспроизведение моего ответа от здесь (в случае его удаления) и добавление отзыва Джеффа Фостера:

Принимая во внимание, что создается исключение OverlappingFileLockException, создается впечатление, что другой поток в том же процессе пытается заблокировать тот же файл. Это не конфликт между A и B, а скорее конфликт внутри B, если кто-то использует документацию API для метода lock () и когда условие, при котором он создает исключение OverlappingFileLockException:

Если блокировка перекрывает запрошенный регион уже удерживается этой Java виртуальная машина, или если другой поток уже заблокирован в этом методе и пытается заблокировать перекрытие область того же файла

Единственное решение, предотвращающее это, состоит в том, чтобы любой другой поток в B не мог получить блокировку для того же файла или той же области перекрытия в файле.

У брошенного IOException есть немного более интересное сообщение. Вероятно, это подтверждает приведенную выше теорию, но, не глядя на весь исходный код, я не могу ничего подтвердить. Ожидается, что метод lock будет блокироваться до тех пор, пока не будет получена эксклюзивная блокировка. Если он был получен, то при чтении из файла не должно возникнуть никаких проблем. За исключением одного условия. Если файл уже был открыт (и заблокирован) одной и той же JVM в другом потоке с использованием объекта File (или, другими словами, второго / другого дескриптора файла), то попытка чтения первого дескриптора файла завершится неудачно, даже если если блокировка была получена (в конце концов, блокировка не блокирует другие потоки).

Усовершенствованный дизайн будет состоять в том, чтобы в каждом процессе имелся отдельный поток, который получает монопольную блокировку файла (при использовании одного объекта File или одного дескриптора файла) только в течение определенного периода времени, выполняя требуемое действие в файл, а затем снимите блокировку.

Как отметил Джефф, использование API-интерфейсов NIO, вероятно, приведет к решению проблемы. Это полностью связано с возможностью API FileReader, открывающего новый дескриптор файла , который отличается от того, для которого получена блокировка.

0 голосов
/ 14 июня 2011

Может быть, то, что вы хотите, это что-то вроде:

FileInputStream fis = new FileInputStream(file);
channel = fis.getChannel();
channel.lock();
bufferedReader = new BufferedReader(new InputStreamReader(fis));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...