1

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

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())? 将方法声明为 throwingInterruptedException并抛出它(讨厌为我所有的 IO 辅助方法这样做)?

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

4

2 回答 2

1

对于任何阻塞 I/O(即 java.io 包),您必须手动检查它并做一些响应它。

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

如果您使用的是通道 (java.nio),则不必这样做。在 NIO 操作之一期间发出的任何线程中断都会导致该操作抛出 ClosedByInterruptException。

于 2012-06-04T19:38:31.833 回答
0

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

于 2012-06-04T14:50:28.843 回答