用于 I/O 超时的最佳异常类型是什么?

What is the best exception type to use for an I/O timeout?

我写了一个 Java class 来实现 "lock file" 以防止周期作业 运行 不止一次并发。它基于 java.nio.channels.FileChannel.tryLock 并且运行良好。

我的 class 允许客户端代码提供一个超时值,指示它愿意等待锁定文件可用多长时间,如果发生超时,我将抛出一个 IOException .这也很有效。

但我想知道是否有 更好的 异常类型可供使用,因为 IOException 相当通用。捕获 IOException 的客户端代码将无法知道问题是否是由于例如超时本身或文​​件系统的其他问题等(当然,除非其他问题抛出 IOException 的 subclass)。

快速浏览 Java API,我看到了一些候选人,但由于各种原因我不太喜欢他们中的任何一个:

  1. java.util.concurrent.TimeoutException(这不是真正的 "concurrent" 用法)
  2. java.nio.channels.FileLockInterruptionException(文档指出了此异常的一个非常具体的原因;与我的情况不符)
  3. java.nio.channels.InterruptedByTimeoutException(原因同上)

有什么建议吗?

如果可能的话,我更喜欢 Java 7 可用的东西。

编辑

显然,自定义异常 class 是可能的,但我想知道标准 API 中是否有合适的内容。

创建一个扩展 IOException 的自定义异常 class。这允许客户端在需要时处理特定异常,或者作为通用 IOException 以及所有其他可能失败的原因。

易于您实施。方便来电者使用。

JDK 包含很多超时异常的变体,如 SQLTimeoutException, SocketTimeoutException 等,但不幸的是,没有父 class 例如 TimeoutException 可以是扩展或通常用于所有超时异常。

所以,你可以写一个自定义的Exception并使用它,如下所示:

public class FileTimeoutException extends IOException {

    private String message;

     public FileTimeoutException(String message) {
           this.message= message;
     }
    //add the other required methods
}

我觉得java.util.concurrent.TimeoutException合适。 javadoc 说:

"Exception thrown when a blocking operation times out. Blocking operations for which a timeout is specified need a means to indicate that the timeout has occurred."

您调用 trylock 的方法是作者设想的意义上的阻塞操作。

您说:"this isn't really a "并发“用法”……但这取决于您的观点。您正在使用 Lock API,并且该接口在 java.util.concurrent 包树中声明。并且大概您正在设计 API 以便它可以轻松地在并发应用程序中使用。 (如果不是……为什么不呢?)


IMO,使用 IOExceptionIOException 的现有或自定义子 class 的唯一 good 参数是,如果客户端操作建模为 I/O 操作。例如,如果 API 使用 I/O 异常来指示其他事情。

另一个反对使用 IOException 的论点是它太笼统了。它说你的 API 方法的调用者 "you need to be prepared for any IOException"。这包括您的 当前 实现不会抛出但未来可能抛出的各种异常。


另一种选择是声明您自己的自定义异常 class,它不是 IOException 的子class。从表面上看,这似乎比 I/O 异常更好。


As for the "implementation detail" issue, the class is designed and documented to use an on-disk file as a locking mechanism. So while it definitely is an implementation detail, it's the definition of the implementation, interface, etc. so I think IOException is at least not inappropriate.

我认为指定这样的 API 是个坏主意。假设您稍后决定另一种锁定可能更合适。如果您在界面中指定了锁定详细信息,则无法更改它们。或者至少,没有 "rewriting the contract" 的方式可能会破坏 API.

的现有客户