Подтвердить что ты не робот

Проверьте, заблокирован ли файл в Java

Моя программа Java хочет прочитать файл, который может быть заблокирован другой программой, записывающей в нее. Мне нужно проверить, заблокирован ли файл, и если да, подождите, пока он будет бесплатным. Как достичь этого?

Программа Java работает на сервере Windows 2000.

4b9b3361

Ответ 1

В Windows с Sun JVM FileLocks должен работать правильно, хотя JavaDocs оставляют надежность довольно неопределенной (зависит от системы).

Тем не менее, если вы только должны распознавать в своей программе Java, что какая-то другая программа блокирует файл, вам не нужно бороться с FileLocks, но просто попробуйте записать в файл, что не удастся, если оно заблокирован. Лучше попробуйте это в своей реальной системе, но я вижу следующее поведение:

File f = new File("some-locked-file.txt");
System.out.println(f.canWrite()); // -> true
new FileOutputStream(f); // -> throws a FileNotFoundException

Это довольно странно, но если вы не считаете, что независимость платформы слишком высока, и ваша система показывает такое же поведение, вы можете объединить ее в служебную функцию.

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

Ответ 2

Должен работать в Windows:

File file = new File("file.txt");
boolean fileIsNotLocked = file.renameTo(file);

Ответ 3

Используйте FileLock во всех приложениях Java, используя этот файл, и запускайте их в одной и той же JVM. В противном случае это невозможно сделать надежно.

Ответ 4

Если несколько процессов (которые могут быть смешением Java и не-Java) могут использовать файл, используйте FileLock, Ключом к успешному использованию блокировок файлов является помнить, что они только "консультативные". Блокировка гарантированно будет видна, если вы ее проверите, но это не помешает вам делать что-то в файле, если вы забудете. Все процессы, которые обращаются к файлу, должны быть разработаны для использования протокола блокировки.

Ответ 5

Вы можете попытаться получить эксклюзивную блокировку файла. Пока исключительная блокировка не может быть получена, другая программа имеет блокировку (эксклюзивную или разделяемую) в файле.

Ответ 6

Лучший способ - использовать FileLock, но в моем случае (jdk 1.6) я попытался с успехом:

public static boolean isFileUnlocked(File file) {
        try {
            FileInputStream in = new FileInputStream(file);
            if (in!=null) in.close();
            return true;
        } catch (FileNotFoundException e) {
            return false;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

Ответ 7

Проверено только на окнах: вы можете проверить, заблокирован ли файл как следующий расширенный ответ venergiac: check for (file.exist()) существует, но с FileNotFoundException означает, что он заблокирован! вы заметите это сообщение (процесс не может получить доступ к файлу, потому что он используется другим процессом)

        public static boolean isFilelocked(File file) {
                try {

                    FileInputStream in = new FileInputStream(file);
                    in.close();
                    return false;
                } catch (FileNotFoundException e) {
                    if(file.exist()){ 
                       return true;
                     }
                     return false;
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return false;
            }

Ответ 8

Улучшенный ответ Амджада Абдул-Гани, я обнаружил, что никаких ошибок не возникало до попытки чтения из файла

public static boolean isFilelocked(File file) {
     try {
         try (FileInputStream in = new FileInputStream(file)) {
             in.read();
             return false;
         }
     } catch (FileNotFoundException e) {
         return file.exists();
     } catch (IOException ioe) {
         return true;
     }
 }

Ответ 9

Я попробовал комбинацию ответов (@vlad) на окнах с доступом к Linux Smb share, и это сработало для меня. Первой части было достаточно для блокировки, как в Excel, но не для некоторых редакторов. Я добавил вторую часть (переименовать) для тестирования обеих ситуаций.

public static boolean testLockFile(File p_fi) {
    boolean bLocked = false;
    try (RandomAccessFile fis = new RandomAccessFile(p_fi, "rw")) {
      FileLock lck = fis.getChannel().lock();
      lck.release();
    } catch (Exception ex) {
      bLocked = true;
    }
    if (bLocked)
      return bLocked;
    // try further with rename
    String parent = p_fi.getParent();
    String rnd = UUID.randomUUID().toString();
    File newName = new File(parent + "/" + rnd);
    if (p_fi.renameTo(newName)) {
      newName.renameTo(p_fi);
    } else
      bLocked = true;
    return bLocked;
  }