【问题标题】:Java retry after IOExceptionIOException 后的 Java 重试
【发布时间】:2012-09-05 21:02:08
【问题描述】:

如果我有我期望有时可能会抛出IOException 的流,并且想要捕获异常并重试流将在哪里(即标记是否仍然在最后一次成功读取块/字节之后)?我只是捕获异常并执行相同的read(byte[]) 并且有任何期望我不会丢失数据吗?谢谢。

【问题讨论】:

  • 据我所知,您将不得不重新开始并启动新的流
  • 你为什么期待 IOException?

标签: java inputstream ioexception


【解决方案1】:

您可以尝试使用来自jcabi-aspectsmark()/reset() 方法、AOP 和Java 注释(我是一名开发人员)。读取的函数将如下所示(伪代码):

@RetryOnFailure(attempts = 5)
private byte[] read(InputStream stream, int length) {
  stream.reset();
  byte[] bytes = new byte[length];
  stream.read(bytes, 0, length);
  stream.mark(length);
  return bytes;
}

如果在 stream.read(bytes, 0, length) 引发 IOException,则不会发生对 mark() 的调用,并且下一次对 reset() 的调用会将指针设置为上一个位置。

【讨论】:

    【解决方案2】:

    一些 IOExceptions 是致命的,你不能指望继续。确保连续重试可能成功。 (即检查手头的异常是否可恢复。)

    【讨论】:

    • 除了“超时”IOExceptions(如 SocketTimeoutException)之外,几乎所有情况都是如此。
    • -1 这些宽泛的概括总是错误的。我今天遇到了一个 IOException (ConnectException),我进行了指数退避/重试,它恢复并继续。
    • OP 没有指定特定类型的 IOException。作为一个类,您必须将 IOExceptions 视为致命的。如果你有一个特定的子类,当然会有可恢复的错误。
    • 这就是为什么您的全面概括(IOExceptions 是致命的)是错误的。 ;)
    • @DonBranson 您在重新连接时没有重复使用相同的Socket:因此对于原始Socket,这不算是“非致命”。一个失败后的第二个Socket.connect() 调用不起作用:你得到“非套接字上的套接字操作”,即它致命的。套接字上唯一可以恢复的IOExceptionSocketTimeoutException
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多