Java线程中InputStream被关闭

3

我将尝试在一个线程中从输入流中读取数据。

这个线程应该运行的类看起来像这样

static private class Runner implements Runnable {

    private InputStream fis;
    private OutputStream fos;

    public Runner(InputStream fis, OutputStream fos) throws IOException {

        int blu = fis.available();

        System.out.println(blu);

        this.fis = fis;

        int bla = this.fis.available();

        System.out.println(bla);
        this.fos = fos;
    }

    @Override
    public void run() {

        try {
            int bla = fis.available();

            System.out.println(bla);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(fis);
        System.out.println(fos);

    }

}

线程是这样创建的:
final Runnable runnable = new Runner(fis, fos);
final Thread thread = new Thread(runnable);
thread.start();

在线程上应该运行run方法。但是一旦执行它就会出现错误。

java.nio.channels.ClosedChannelException

我调试了一下,发现InputStream已经关闭。

为什么InputStream会在线程中被关闭呢?有没有其他的替代方法可以使用?

编辑:

我忘记提到它们是在try块中打开的,就像这样,在那之后主函数就结束了。

try (InputStream fis = Files.newInputStream(sourcePath)) {
        try (OutputStream fos = Files.newOutputStream(sinkPath)) {

            final Runnable runnable = new Runner(fis, fos);
            final Thread thread = new Thread(runnable);
            thread.start();
        }

    }

你发送的代码没有关闭。这些流从哪里来? - Oskar Kjellin
我添加了更多的程式碼。主線程是否已經關閉了它們,因為該代碼塊已運行完畢,因此它們可以被釋放? - b-m-f
1
是的,你最新的代码显示了你的错误。给回答者加1分。删除我之前的评论。将来请考虑创建并发布一个最小、完整和可验证的示例程序,这样我们就可以更快地回答你,而不必从你那里提取更多信息。祝你好运。 - Hovercraft Full Of Eels
2个回答

5

当使用try-with-resources块时,这些块将在块退出时关闭它们各自的流。当您仅计划在块内部使用流时,这非常好。但是,如果您希望在块结束后在另一个线程中继续使用流,请摆脱这些块。

InputStream  fis = Files.newInputStream (sourcePath);
OutputStream fos = Files.newOutputStream(sinkPath);

final Runnable runnable = new Runner(fis, fos);
final Thread   thread   = new Thread(runnable);
thread.start();

3

因为您将它放在“尝试”中,所以当线程离开try块时,它会被关闭。Thread.start()不会挂起,因此它会自动关闭。

请执行以下操作:

InputStream  fis = Files.newInputStream (sourcePath);
OutputStream fos = Files.newOutputStream(sinkPath);

final Runnable runnable = new Runner(fis, fos);
final Thread thread = new Thread(runnable);
thread.start();

在你的线程中:

   public void run() {

        try {
            int bla = fis.available();

            System.out.println(bla);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            System.out.println(fis);
            System.out.println(fos);
            fis.close();
            fis.close();
        }
    }

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