Should Supplier be used to supply File Stream?

Viewed 226

I needed to supply a Stream of a file more than once so that different operations could be executed upon it at different times, I used the following Supplier:

Supplier<Stream<String>> linesSupplier = () -> {
    try
    {
        return Files.lines(Paths.get(file.toURI()));
    }
    catch (IOException e)
    {
        log.error("Error while supplying file " + file.getName(), e);
    }
    return null;
};

Unfortunately, it leads to a file handle leak, so I tried to use a try-with-resource as suggested.

Supplier<Stream<String>> linesSupplier = () -> {
    try(Stream<String> lines = Files.lines(Paths.get(file.toURI())))
    {
        return lines;
    }
    catch (IOException e)
    {
        log.error("Error while supplying file " + file.getName(), e);
    }
    return null;
};

But now the first time I use linesSupplier.get(), I get a java.lang.IllegalStateException.

Is it a sign that I should try to actively avoid Supplier, whatever the circumstances?

1 Answers

Of course not - you should use a Supplier when you need to. The problem here is that Stream class implements AutoCloseable and your try-with-resource is calling it's close method after it ends.

As such, one should either make the Supplier responsible of closing the Stream by moving the try-with-resource or one could return something else as a Stream, for example, a List<String>.

Related