12

Here is a line reading a file into a List:

List<String> lines =
    new BufferedReader(
        new InputStreamReader(classLoader.getResourceAsStream(fileName)))
            .lines()
            .collect(Collectors.toList());

Is this correct or should I assign the BufferedReader to a variable to be able to close it later?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Ekaterina
  • 1,642
  • 3
  • 19
  • 36
  • [This](https://stackoverflow.com/questions/31171489/does-collect-operation-on-stream-close-the-stream-and-underlying-resources) seems to imply close is *not* called by collect. – TiiJ7 Feb 26 '19 at 15:35
  • @MS90, could you provide a link which you mean? – Ekaterina Feb 26 '19 at 16:16
  • Sorry, take a look down below from official documentation in my reply. @Ekaterina – MS90 Feb 26 '19 at 17:11

3 Answers3

13

You should always close your resources. Closing may not be a big problem for small programs which only use a couple of files quickly, since most mature OSes will close the files for you when the process completes. However, there are usually limits on how many files you can have open at one time. It is good to be tidy, so that you don't hit those limits when you start writing bigger programs. There are also other types of resources, like network and serial ports, which you may want to let others use once your program is done with them, even if it is still running.

An alternative to closing the file manually is using try-with-resources syntax, which ensures that the file will be closed properly even in case of an error:

List<String> lines;
try(BufferedReader reader = new BufferedReader(
        new InputStreamReader(classLoader.getResourceAsStream(fileName)))) {
    lines = reader.lines().collect(Collectors.toList());
}
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
6

Well, in your concrete example, the stream opened by

classLoader.getResourceAsStream(fileName)

is never closed. This stream must be closed - it is most likely a file handle in the local system. You can close it by closing the BufferedReader, which closes the wrapped InputStreamReader, which closes the underlying InputStream. You could instead also store a reference to the original InputStream and only close this.

Please also have a look into try-with-resources, this could potentially make things easier for you here.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Florian Albrecht
  • 2,266
  • 1
  • 20
  • 25
0

I stand corrected


From documentation: Streams have a close() method and implement AutoCloseable interface, but nearly all stream instances do not actually need to be closed after use.

Generally, only streams whose source is an IO channel, for example a BufferedReader.lines will require closing.

Most streams are backed by collections, arrays, or generating functions, which require no special resource management. If a stream does require closing, it can be declared as a resource in a try-with-resources statement.

MS90
  • 1,219
  • 1
  • 8
  • 17