Блокировка файлов Java и Windows - блокировка не является «абсолютной»? - PullRequest
6 голосов
/ 27 августа 2009

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

Пример кода следующий:

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
  • Затмение отказывается открывать его

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

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

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

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

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

ш, Ток

Ответы [ 2 ]

5 голосов
/ 27 августа 2009

Хитрый, сам FileLock API не обещает многого:

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

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

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

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

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

1 голос
/ 23 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...