b-m-f
b-m-f

Reputation: 1328

Java InputStream closed in Thread

I am trying to read from an InputStream in a Thread.

The class that the Thread should run looks like this

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);

    }

}

The Thread gets created like this

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

And on the Thread should run the run method. But as soon as it is executed I get the Error

java.nio.channels.ClosedChannelException

I debugged it and the InputStream is set to closed.

Why does the InputStream get closed in the Thread? Is there an alternative I should use?

EDIT:

I forgot to mention that they are opened in a try block like this and the main function is over after that.

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();
        }

    }

Upvotes: 3

Views: 2414

Answers (2)

Oskar Kjellin
Oskar Kjellin

Reputation: 21880

Because you have it in the Try, it's closed when the thread leaves the try block. Thread.start() does not hang so it's automatically closed.

Do this:

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();

And in your thread:

   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();
        }
    }

Upvotes: 3

John Kugelman
John Kugelman

Reputation: 361635

Those try-with-resources blocks will close their respective streams when the block exits. This is great when you only plan to use the streams inside the blocks. But since you want to continue using the streams in another thread after the blocks end, get rid of the blocks.

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();

Upvotes: 5

Related Questions