Как проверить, открыт ли файл другим процессом (Java / Linux)? - PullRequest
26 голосов
/ 18 февраля 2012

Я пытаюсь проверить, открыт ли какой-либо файл java.io.File внешней программой. В Windows я использую этот простой трюк:

try {
    FileOutputStream fos = new FileOutputStream(file);
    // -> file was closed
} catch(IOException e) {
    // -> file still open
}

Я знаю, что системы на основе Unix позволяют открывать файлы в нескольких процессах ... Есть ли подобный прием для достижения того же результата для систем на основе Unix?

Любая помощь / взлом высоко ценится: -)

Ответы [ 5 ]

9 голосов
/ 22 мая 2013

Вот пример использования lsof для систем на основе Unix:

public static boolean isFileClosed(File file) {
    try {
        Process plsof = new ProcessBuilder(new String[]{"lsof", "|", "grep", file.getAbsolutePath()}).start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(plsof.getInputStream()));
        String line;
        while((line=reader.readLine())!=null) {
            if(line.contains(file.getAbsolutePath())) {                            
                reader.close();
                plsof.destroy();
                return false;
            }
        }
    } catch(Exception ex) {
        // TODO: handle exception ...
    }
    reader.close();
    plsof.destroy();
    return true;
}

Надеюсь, это поможет.

3 голосов
/ 08 июля 2013

Это также должно работать для систем Windows. Но внимание, не работает для Linux!

     private boolean isFileClosed(File file) {  
            boolean closed;
            Channel channel = null;
            try {
                channel = new RandomAccessFile(file, "rw").getChannel();
                closed = true;
            } catch(Exception ex) {
                closed = false;
            } finally {
                if(channel!=null) {
                    try {
                        channel.close();
                    } catch (IOException ex) {
                        // exception handling
                    }
                }
            }
            return closed;
    }
3 голосов
/ 18 февраля 2012

Вы можете запустить из Java-программы утилиту lsof Unix, которая сообщит вам, какой процесс использует файл, а затем проанализирует его вывод. Чтобы запустить программу из кода Java, используйте, например, классы Runtime, Process, ProcessBuilder. Примечание: в этом случае ваша Java-программа не будет переносимой, что противоречит концепции переносимости, поэтому подумайте дважды, действительно ли вам это нужно:)

1 голос
/ 08 июля 2013

Спасибо за оригинальное предложение. У меня есть одно небольшое обновление, которое несколько важно для этого метода:

FileOutputStream fos = null;
try {
    // Make sure that the output stream is in Append mode. Otherwise you will
    // truncate your file, which probably isn't what you want to do :-) 
    fos = new FileOutputStream(file, true);
    // -> file was closed
} catch(IOException e) {
    // -> file still open
} finally {
    if(fos != null) {
    try {
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ура, Gumbatron

1 голос
/ 18 февраля 2012

Вы можете попробовать этот код типа семафора для блокировки файла с помощью @ZZ Coder

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

FileLock lock = channel.lock();
try {
    lock = channel.tryLock();
    // Ok. You get the lock
} catch (OverlappingFileLockException e) {
    // File is open by someone else
  } finally {
   lock.release();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...