2012-02-18 84 views
24

我想检查某个java.io.File是否由外部程序打开。在Windows上我用这个简单的一招:如何检查一个文件是否被另一个进程(Java/Linux)打开?

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

我知道,基于UNIX的系统允许多个进程打开文件...是否有类似的伎俩,以实现基于UNIX的系统相同的结果?

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

+0

你是绝对正确的......但我需要这个功能来监视文件状态(我使用Java 7中的WatchServices做的)。但我还需要检测特定文件何时再次关闭才能解锁,以便其他用户可以再次编辑它。 – salocinx 2012-02-18 16:58:13

+0

你可以叫出'lsof'吗? – tchrist 2012-02-18 17:03:01

+0

这是我将尝试做的下一件事。 lsof似乎存在于众多的linux发行版中。用lsof打开一个新的流程并读出标准输出将完成这项工作。我将在明天的主题中介绍我的解决方案。非常感谢! – salocinx 2012-02-19 23:13:39

回答

0

您可以通过@ZZ编码器尝试文件锁定该信号类型代码

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

非常感谢,我会试试看! – salocinx 2012-02-18 13:45:49

+0

我的荣幸@NicolasBaumgardt :) – 2012-02-18 13:48:34

+3

只有在其他人使用此代码时才有效。一点也不现实。 – tchrist 2012-02-18 13:50:56

3

可以从Java程序中的lsof Unix工具运行告诉你哪个进程正在使用一个文件,然后分析它的输出。要从Java代码运行程序,请使用例如RuntimeProcessProcessBuilder类。注意:你的Java程序将无法在这种情况下,便携,顶撞便携概念,所以三思而后行,你是否真的需要这个:)

+0

非常感谢您的解决方案。我知道我正在进入可移植性问题 - 但目标平台仅限于win/unix/mac。希望我会为每个操作系统找到一个“稳固”的策略:-) – salocinx 2012-02-18 14:07:15

+5

更大的问题是不可移植性,但即使使用lsof并分析其输出,并且看到没有人使用此文件,也无法保证在下一个在你的代码行没有打开你感兴趣的文件 – 2013-04-01 15:39:32

8

下面是一个示例如何使用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; 
} 

希望这有助于。

+0

似乎不适用于Android。 – 2015-04-19 20:30:20

1

感谢您的原始建议。我有一个小的提升,其对方法比较重要:

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

+0

注意:不适用于Linux。即使正在使用,您仍然可以打开该文件。 – mdewit 2015-06-24 15:32:34

3

这其中也应该适用于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; 
    } 
相关问题