等待文件锁被释放

时间:2016-03-24 22:39:27

标签: java io fileutils

有一些类似于这个问题的Java问题,但是没有一个问题能够接受我能找到的答案,而且我的情况更具体一些。我有一个程序,当它们被送入目录时,一次处理一个文件。有时,文件可能会被程序保持锁定状态,以便程序在我的程序可见之后将其关闭几秒钟。我无法控制该程序。在我的程序中,我已经有错误处理,以便在我的程序尝试读取文件时使用该文件。它导致文件被完全跳过。我想要实现的是一个重试方案,以查看文件是否在几秒钟后解锁。在这里的另一个问题中,我发现了使用FileUtils.touch()的建议。这很方便,因为我已经在我的项目中使用了FileUtils。根据javadoc,FileUtils.touch()如果该文件正由另一个进程使用,则抛出IOException。听起来不错。但是,我提到的答案中的一条评论警告说没有任何解释的竞争条件。以下是我考虑实施的代码:

// Implementing Sason's suggestion
int retries = 0;
while (retries < MAX_RETRIES) {
    try {
        processFile(file);
    } catch (IOException ioe) {
        // Assumes this is a file in use exception... bad thing?
        log.warn("File is in use.  Waiting 1 second to retry.");
        retries++;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ie) {
            log.warn("Thread interrupted while waiting for file lock to clear.");
            break;
        }
    }
}

我意识到文件可能会在FileUtils.touch()和processFile()方法调用之间再次被锁定(并且我认为这是在我发现的未接受的答案中警告的竞争条件)但是&#39很好。 processFile()方法将像当前一样处理锁定错误。为了清楚起见,在这种情况下,文件可以被另一个进程打开,但它无法锁定。

此外,虽然有时文件在一两秒后解锁,但在某些情况下,程序从文件中删除会无限期地保持锁定状态。我还需要避免无限尝试重新处理同一个文件,以及在重试耗尽后无法处理文件时能够通知发件人。

我在这里错过了一些东西吗?是否有更好/更安全的方法来做到这一点?

1 个答案:

答案 0 :(得分:3)

我会使用SchedueledExecutorService提交一些尝试处理文件的延迟。如果处理失败,请一次又一次地发布工作,直到成功为止。

这里是否需要FileUtils.touch?为什么不尝试读取文件并重试失败?

thread.sleep的东西有点难看。如果处理多个文件,每个文件都必须使用它自己的线程,直到完成为止。 SchedueledExecutorService会更有效率。