2012-02-18 20 views
24

特定のjava.io.Fileが外部プログラムによってオープンされているかどうかを確認しようとしています。 Windowsでは、私はこの単純なトリックを使用します...私は、UNIXベースのシステムでは、複数のプロセスでファイルを開くことが許可されていることを知っているファイルが別のプロセス(Java/Linux)によって開かれているかどうかをチェックする方法は?

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

をUNIXベースのシステムのために同じ結果を達成するために、同様のトリックがありますか?

すべてのヘルプ/高度

+0

あなたは本当に正しいですが、ファイルの状態を監視するにはこの機能が必要です(これはJava 7のWatchServicesで行います)。特定のファイルが再び閉じられたときにそれを検出してロックを解除し、他のユーザーが再びそのファイルを編集できるようにする必要があります。 – salocinx

+0

'lsof'を呼び出せますか? – tchrist

+0

これは私がやろうとしている次のものです。 lsofは非常に多くのLinuxディストリビューションに存在するようです。 lsofで新しいプロセスをオープンし、標準出力を読み出すと、その作業が行われます。私は明日このスレッドで私のソリューションを提示します。今までありがとう! – salocinx

答えて

0

:-)感謝ハックあなたは、あなたがそのJavaプログラムからlsofのUnixユーティリティを実行することができます@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

+0

私の喜び@NicolasBaumgardt :) –

+3

これは、他の人がこのコードを使用している場合にのみ機能します。少なくとも現実的ではない。 – tchrist

3

をファイルロックのために、このセマフォタイプコードを試すことができますどのプロセスがファイルを使用しているかを示し、その出力を分析します。 Javaコードからプログラムを実行するには、たとえば、Runtime,ProcessProcessBuilderクラスを使用します。注:Javaプログラムが、この場合には移植できないだろう移植性の概念と矛盾するので、あなたが本当にこれを必要とするかどうかを考え直す:)

+0

あなたのソリューションに感謝します。私は移植性の問題に遭遇していることを知っていますが、ターゲットプラットフォームはwin/unix/macに限られています。 – salocinx

+5

より大きな問題は移植性ではありませんが、lsofを使って出力を分析しても誰もこのファイルを使用していないとしても、次のことについては何も保証しませんあなたのコードの行に何かがあなたが興味を持っているファイルを開いていない –

8

ここでは、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; 
} 

これが役に立ちます。

+0

は、Android上で動作していないようです。 –

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

3

また、Windowsシステムのために働く必要があり、この1:私は、その方法にやや重要である一つの小さなアップグレードを持っています。しかし注意は、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; 
    }