【问题标题】:How to determine if file is in use by another process (Java)如何确定文件是否被另一个进程使用(Java)
【发布时间】:2013-04-15 08:17:04
【问题描述】:

我尝试了很多示例,但没有一个有效。 我试试这个,但不工作。

我也尝试使用tryLock()。它总是返回假。为什么?

private boolean checkCompleteFile(File f)
{           
    RandomAccessFile file = null;
    FileLock fileLock = null;

    try
    {
        file = new RandomAccessFile(f, "rw");
        FileChannel fileChannel = file.getChannel();

        fileLock = fileChannel.lock();
        if (fileLock != null)
        {
            fileLock.release();
            file.close();
            return false;
        }

    }
    catch(Exception e)
    {
         return false;
    }

    return true;
}

【问题讨论】:

  • 什么不起作用?您从此处提供的代码中得到什么结果?你期待什么结果?
  • 我总是可以锁定文件,即使文件正在被写入!!!
  • 您的代码没有意义。您返回 true 的唯一时间是 FileChannel.lock() 返回 null,,这是它永远无法做到的。在这种情况下,您也会泄漏通道,但它永远不会真正发生。如果您设法获得了锁,则意味着没有其他人锁定它:在这种情况下您确定要返回true

标签: java linux file-io


【解决方案1】:

你捕获一个异常并返回 false,这就是为什么你总是得到 false,对异常做一些事情或者不捕获它,这样你就知道是否抛出了异常,如果你捕获到一个一般异常,一个 false 返回值是意义不大。

try {
  lock = channel.tryLock();
  // ...
} catch (OverlappingFileLockException e) {
  // File is already locked in this thread or virtual machine
}
lock.release();
channel.close();

您只需尝试访问文件并在失败时捕获异常:

boolean isLocked=false;
RandomAccessFile fos=null;
try {
      File file = new File(filename);
      if(file.exists())
        fos=new RandomAccessFile(file,"rw");        
}catch (FileNotFoundException e) {
    isLocked = true;
}catch (SecurityException e) {
    isLocked = true;
}catch (Exception e) {
    // handle exception
}finally {
    try {
        if(fos!=null) {
            fos.close();
        }
    }catch(Exception e) {
        //handle exception
    }
}

注意RandomAccessFile 类抛出:

FileNotFoundException -

如果模式是“r”但给定的字符串是 不表示现有的常规文件,或 如果模式以“rw”开头 但给定的字符串并不表示现有的可写正则 文件和该名称的新常规文件无法创建,或者如果某些 打开或创建文件时出现其他错误。

SecurityException -

如果安全管理器存在并且它的 checkRead 方法拒绝对文件的读取访问或模式为“rw”并且 安全管理器的 checkWrite 方法拒绝对文件的写访问

【讨论】:

  • 这表示“文件是否已锁定在此线程或虚拟机中”,但我想知道文件是否被某人打开。
  • 你刚刚访问 fila 并捕获了 AccessDeniedException 吗?
【解决方案2】:

试试这个:

try {
    @SuppressWarnings("resource")
    FileChannel channel = new RandomAccessFile(fileToRead, "rw").getChannel();
    //This method blocks until it can retrieve the lock. 
    FileLock lock = channel.lock(); // Try acquiring the lock without blocking. 
    try { 
        lock = channel.tryLock();
    } catch (OverlappingFileLockException e){

    }
    lock.release(); //close the file.
    channel.close();
} catch (Exception e) {             

}

【讨论】:

    【解决方案3】:

    使用linux命令怎么样?

    lsof -p 
    

    该命令将显示文件打开状态,您可以对其进行解析以检查谁使用它。

    【讨论】:

    • 这应该是评论而不是答案
    • 这是一个了不起的答案。
    猜你喜欢
    • 1970-01-01
    • 2011-08-31
    • 2011-09-23
    • 1970-01-01
    • 2012-03-09
    • 2013-01-09
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    相关资源
    最近更新 更多