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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9341505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:39:20  来源:igfitidea点击:

How to check if a file is open by another process (Java/Linux)?

javalinuxfile

提问by salocinx

I am trying to check if a certain java.io.File is open by an external program. On windows I use this simple trick:

我正在尝试检查某个 java.io.File 是否被外部程序打开。在 Windows 上,我使用这个简单的技巧:

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

I know that unix based systems allow to open files in multiple processes... Is there a similar trick to achieve the same result for unix based systems ?

我知道基于 unix 的系统允许在多个进程中打开文件......是否有类似的技巧可以为基于 unix 的系统实现相同的结果?

Any help / hack highly appreciated :-)

任何帮助/黑客高度赞赏:-)

回答by Aishwarya Shiva

You can try this semaphore type code for a file lock by @ZZ Coder

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

回答by Alexey Berezkin

You can run from Java program the lsofUnix utility that tells you which process is using a file, then analyse its output. To run a program from Java code, use, for example, Runtime, Process, ProcessBuilderclasses. Note: your Java program won't be portable in this case, contradicting the portability concept, so think twice whether you really need this :)

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

回答by Hans Frankenstein

Here's a sample how to use lsoffor unix based systems:

以下是如何将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;
}

Hope this helps.

希望这可以帮助。

回答by Gumbatron

Thanks for the original suggestion. I have one small upgrade that is somewhat important to that method:

感谢您的原始建议。我有一个小升级,它对该方法有些重要:

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

Cheers, Gumbatron

干杯,Gumbatron

回答by salocinx

This one should also work for Windows systems. But attention, does not work for Linux!

这个也应该适用于 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;
    }