Блокировка файлов Java и Windows - блокировка не является "абсолютной”?

StackOverflow https://stackoverflow.com/questions/1339306

  •  20-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь заблокировать файл с помощью Java в среде Windows с помощью Блокировка файлов и у меня возникла проблема :после того, как я заблокирую файл, к нему все еще могут получить доступ другие процессы, по крайней мере, на каком-то уровне.

Ниже приведен пример кода:

public class SimpleLockExample {
    public static void main(String[] args) throws Exception {
        String filename = "loremlipsum.txt";

        File file = new File(filename);
        RandomAccessFile raf = new RandomAccessFile(file, "rw");
        FileChannel channel = raf.getChannel();

        FileLock lock = null;
        try {
            lock = channel.tryLock();
            String firstLine = raf.readLine();
            System.out.println("First line of file : " + firstLine);
            waitForEnter();
            lock.release();
        } catch (OverlappingFileLockException e) {
            e.printStackTrace();
        }

        lock.release();
        System.out.println("Lock released");

        channel.close();
    }

    private static void waitForEnter() throws Exception {
        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));
        reader.readLine();
        reader.close();
    }
}

Теперь, когда я блокирую свой файл с помощью этого примера, он блокируется :

  • Он не может быть удален Windows
  • Eclipse отказывается его открывать

...но он все еще не полностью пуленепробиваемый:

  • Например, если я открываю его с помощью Scite (текстовый редактор), содержимое не отображается, но если я выбираю сохранить файл (пустой при открытии или с некоторым записанным содержимым), все завершается успешно, и содержимое файла очищается...(после этого там не будет никакого контента, даже если бы я написал что-то с помощью Scite)

Есть ли какой-нибудь способ предотвратить полную перезапись / очистку файла другими процессами с Java в Windows?

Если я правильно понял, я использую банкомат с эксклюзивной блокировкой.С общей блокировкой можно сделать еще больше вещей.

Этот тест был запущен в Windows 2000.

br, Тоуко

Это было полезно?

Решение

Сложно сказать, что сам по себе FileLock API не обещает многого:

Этот API для блокировки файлов предназначен для прямого сопоставления с собственным средством блокировки базовой операционной системы.Таким образом, блокировки файла должны быть видны всем программам, которые имеют доступ к файлу, независимо от языка, на котором эти программы написаны.

Является ли блокировка на самом деле предотвращает доступ другой программы к содержимому заблокированного регион зависит от системы и поэтому не указан.Встроенные средства блокировки файлов некоторых систем носят чисто рекомендательный характер, что означает что программы должны совместно соблюдать известный протокол блокировки, чтобы гарантировать целостность данных.В других системах собственные блокировки файлов обязательны, что означает, что если одна программа блокирует область файла, то другим программам фактически запрещается доступ к этой области способом, который нарушил бы блокировку.В других системах, являются ли встроенные блокировки файлов консультативными или обязательными, настраивается для каждого файла.Для обеспечения последовательного и правильного поведения во всех платформам настоятельно рекомендуется использовать блокировки, предоставляемые этим API , как если бы они были консультативными блокировками.

Как ни странно, в обсуждении API блокировки файлов, когда он находился в стадии разработки, утверждалось, что ОС Windows обеспечивала обязательный блокировка и в Unix только рекомендательная блокировка.Таким образом, при таком прочтении можно ожидать, что ваш код будет отлично работать в Windows.

Интересно, не происходит ли так, что ваш редактор не столько изменяет файл, сколько создает временный файл, а затем манипулирует записями каталога, чтобы заменить версию файла, которую вы заблокировали, новой версией.Допустит ли Windows такое поведение?

Интересно, нужно ли вам прибегать к JNI, чтобы получить необходимый вам уровень контроля.

Другие советы

Ваш вызов функции .tryLock() может вернуть значение null, если он не получит блокировку.Из Javadoc:

Объект блокировки, представляющий вновь полученную блокировку, или null, если блокировку не удалось получить, поскольку другая программа содержит перекрывающуюся блокировку

Кроме того, ваш код в данный момент открывает файл а потом он пытается установить блокировку.Вместо этого вы должны зацикливаться, пытаясь получить блокировку, и как только вы ее получите, откройте файл, прочитайте файл, закройте файл, затем снимите блокировку.И отказаться от замка в finally {} оговорка, на всякий случай, если ваш код выдает исключение с удерживаемой блокировкой.(Вам когда-нибудь приходилось перезагружать компьютер с Windows только потому, что какой-то файл был заблокирован?)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top