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



我编写了一个Java类,它实现了一个"锁定文件",以防止周期作业同时运行多次。它基于java.nio.channels.FileChannel.tryLock并且运行良好。

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

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

简要浏览Java API,我看到了一些候选者,但由于各种原因,我不太喜欢其中任何一个:

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

有什么建议吗?

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

编辑

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

我认为java.util.concurrent.TimeoutException是合适的。 javadoc 说:

"阻止操作超时时引发异常。为其指定超时的阻止操作需要一种方法来指示超时已发生。

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

你说:"这不是真正的"并发"用法"......但这取决于你的观点。 您使用的是LockAPI,并且该接口在java.util.concurrent包树中声明。 据推测,您正在设计 API,以便可以轻松地在并发应用程序中使用它。 (如果没有...为什么不呢?


IMO,使用IOExceptionIOException的现有或自定义子类的唯一论据是客户端操作建模为 I/O 操作。 例如,如果 API 使用 I/O 异常来发出其他信号。

反对使用IOException的另一个论点是它太笼统了。 它说你的API方法的调用者"你需要为任何IOException做好准备"。这包括您当前实现不会抛出的各种异常,但将来可能会抛出。


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


至于"实现细节"问题,该类被设计和记录为使用磁盘文件作为锁定机制。因此,虽然它肯定是一个实现细节,但它是实现、接口等的定义,所以我认为 IOException 至少不是不合适的。

我认为指定这样的 API 是一个坏主意。 假设您稍后决定另一种锁定可能更合适。 如果您在界面中指定了锁定详细信息,则无法更改它们。 或者至少,并非没有以可能破坏 API 现有客户端的方式"重写合约"。

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

易于实施。易于调用方使用。

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

因此,您可以编写自定义异常并使用它,如下所示:

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

最新更新