InputStream - 关闭、中断阻塞read()

4
一些输入输出对象(如InputStream)不支持中断,并且在读写期间源不能被关闭。
例如:
class InputStreamOperation1 implements Runnable
{
    static InputStream stream;

    InputStreamOperation1(InputStream stream) { this.stream = stream; }

    public void run()
    {
        System.out.println("InputStreamOperation - the beginning");
        try
        {
            stream.read(); //blocking operation
        } catch (Exception e)
        {
            System.out.println("InputStreamOperation interrupted");
        }
        System.out.println("InputStreamOperation - the end");
    }
}

尝试中断:

ExecutorService executor = Executors.newCachedThreadPool();
Future<?> f = executor.submit(new InputStreamOperation1(System.in));
TimeUnit.MILLISECONDS.sleep(100);
System.out.println("Interrupting InputStream");
f.cancel(true); // Interrupts if running
System.out.println("Interrupt sent to InputStream");

尝试关闭源代码
Future<?> f = executor.submit(new InputStreamOperation1(System.in));
TimeUnit.MILLISECONDS.sleep(100);
System.out.println("Closing source in InpuStream");
try
{
      System.in.close();
} catch (IOException e)
{
      System.out.println("Error during closing InputStreamOperation");
}
System.out.println("Closed source in InputStream");

两种解决方案都不起作用。在读入至少一个字母后,它会中断或关闭。
我的问题是:有没有办法在阻塞的read()操作期间中断或关闭源?
我在这里找到了类似的东西 - Is it possible to read from a InputStream with a timeout?。我想知道是否还有其他解决方案(特别是使用中断或关闭源),以停止线程,或者唯一的方法是与那个棘手的方式相关联。

这里有另一个相关的问题:链接 - Andrew Logvinov
@Andrew Longvinov 是的,但它与 InterruptibleChannel 相关联,解决方案与使用另一个类的建议相关。 - Pawel
1个回答

1
两种解决方案都无效。在读取至少一个字母后会中断或关闭。
关闭System.in对我有效。
我的输出如下:
InputStreamOperation - the beginning
Closing source in InpuStream
Closed source in InputStream
read: -1
InputStreamOperation - the end

我添加了读取结果的打印,显示为-1,意味着在另一个线程中关闭System.in时已到达文件末尾。
我想知道你的问题是否是没有关闭ExecutorService?如果没有关闭,你的应用程序将无法完成。
ExecutorService executor = Executors.newCachedThreadPool();
Future<?> f = executor.submit(new InputStreamOperation1(System.in));
executor.shutdown();

如果您仍然无法正常工作,那么这可能是与操作系统有关。在我的OSX和Linux系统下可以正常工作。
我的问题是:是否有办法在阻塞的read()操作期间中断或关闭源?
除了关闭流(这对我总是有效的)之外,我知道的唯一其他方法是使用NIO InterruptibleChannel类并中断它。
编辑:
从评论中可以看出,您正在使用Netbeans,并且可能是因为Web包装器出于安全目的而保护了System.in。

1
我关闭了 ExecutorService。你是通过终端运行的吗?我是在 NetBeans 中运行的。可能,System.in 有所不同。 - Pawel
是的,他们可能不允许您访问真正的 System.in - Gray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接