如何检查文件是否由另一个进程(Java/Linux)打开?

如何检查文件是否由另一个进程(Java/Linux)打开?,java,linux,file,Java,Linux,File,我试图检查某个java.io.File是否被外部程序打开。在windows上,我使用以下简单技巧: try { FileOutputStream fos = new FileOutputStream(file); // -> file was closed } catch(IOException e) { // -> file still open } 我知道基于unix的系统允许在多个进程中打开文件。。。对于基于unix的系统,是否有类似的技巧来实现相同的

我试图检查某个java.io.File是否被外部程序打开。在windows上,我使用以下简单技巧:

try {
    FileOutputStream fos = new FileOutputStream(file);
    // -> file was closed
} catch(IOException e) {
    // -> file still open
}
我知道基于unix的系统允许在多个进程中打开文件。。。对于基于unix的系统,是否有类似的技巧来实现相同的结果


非常感谢任何帮助/黑客:-)

您可以通过@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();
}

您可以从Java程序运行
lsof
Unix实用程序,它告诉您哪个进程正在使用文件,然后分析其输出。要从Java代码运行程序,请使用,例如,
Runtime
Process
ProcessBuilder
类。注意:在这种情况下,您的Java程序将不会是可移植的,这与可移植性概念相矛盾,因此请仔细考虑您是否真的需要它:)

下面是一个如何为基于unix的系统使用lsof的示例:

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;
}

希望这能有所帮助。

谢谢你最初的建议。我有一个小的升级,这对该方法有点重要:

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

这一款也适用于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;
    }

我的荣幸@NicolasBaumgardt:)只有在其他人都使用此代码的情况下才有效。至少不现实。它在ubuntu/linux上不起作用。文件系统允许我获取锁,即使文件已经在另一个进程中打开。但它适用于windows。有人知道如何在linux上实现相同的结果吗???非常感谢您的解决方案。我知道我遇到了可移植性问题,但目标平台仅限于win/unix/mac。希望我能为每个操作系统找到一个“可靠”的策略:-)更大的问题不是可移植性,但即使您使用lsof并分析其输出,发现没有人在使用此文件,也不能保证在代码的下一行中有什么东西没有打开您感兴趣的文件您完全正确。。。但是我需要这个功能来监视文件状态(我在Java7中使用WatchServices时就是这样做的)。但我还需要检测某个特定文件何时被再次关闭以解锁,以便其他用户可以再次编辑它。这是我将尝试做的下一件事。lsof似乎存在于相当多的linux发行版上。使用lsof打开一个新流程并读取标准输出即可。明天我将在这篇文章中提出我的解决方案。谢谢你!在我看来,目前还没有可移植的解决方案。注意:在Linux上不起作用。即使文件正在使用中,您仍可以打开该文件。