处理IO中断的优雅方法是什么?

时间:2012-06-04 14:47:42

标签: java io

我正在http://www.docjar.com/html/api/org/apache/commons/io/IOUtils.java.html查看来自Apache Commons的IOUtils.copy()的实现,最终归结为:

public static long copyLarge(InputStream input, OutputStream output)
        throws IOException {
    // DEFAULT_BUFFER_SIZE is 4096
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    long count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}

我在Executor中运行此任务,该任务有超时等但如果我理解正确,即使它超时并取消Future,该线程仍会继续运行,因为有在此循环中的任何位置都不检查线程状态。这会导致危险的泄漏和饥饿。

似乎我需要重写循环,但处理这个问题的理智和正确方法是什么? throw new IOException(new InterruptedException())?将方法声明为抛出InterruptedException并抛出它(讨厌为我的所有IO辅助方法执行此操作)?

编辑 :我刚从Guava检查ByteStreams,他们似乎在做同样的事情。现在我想知道为什么两个主要的库不支持这种循环中的中断。我错过了什么吗?

2 个答案:

答案 0 :(得分:1)

如果您关闭input和/或outputcopyLarge方法将抛出异常,退出循环。

答案 1 :(得分:1)

对于任何阻塞I / O(即java.io包),您必须手动检查并执行某些操作以响应它。

if (Thread.currentThread().isInterrupted()) { 
    // do something here to stop processing
}

如果您正在使用频道(java.nio),则不必执行此操作。在其中一个NIO操作期间发出的任何线程中断都会导致该操作抛出ClosedByInterruptException。