javaspringjava-streamtry-catch-finallytry-with-resources

Use try-with-resources or close this 'Stream' in a "finally" clause


I am using Files.walk() to get some files from directory stuff but I am getting a warning about blocker bug from Sonarqube and Sonarlint code analysis that

Connections, streams, files, and other classes that implement the Closeable interface or its super-interface, AutoCloseable, needs to be closed after use. Further, that close call must be made in a finally block otherwise an exception could keep the call from being made. Preferably, when class implements AutoCloseable, resource should be created using "try-with-resources" pattern and will be closed automatically.

Here is the code:

Files.walk(Paths.get(ifRecordsPath))
        .filter(Files::isDirectory)
        .map(ifRecordsCollector)
        .map(ifRecordStreamAccumulator)
        .forEach(ifRecordCollection::addAll);

return ifRecordCollection;

I read this post and almost got the problem but I do not know how exactly I stop the stream in correct place. When I add the finally block, it is still giving the same error

try {
    Files.walk(Paths.get(ifRecordsPath))
            .filter(Files::isDirectory)
            .map(ifRecordsCollector)
            .map(ifRecordStreamAccumulator)
            .forEach(ifRecordCollection::addAll);
} finally {
    Files.walk(Paths.get(ifRecordsPath)).close();
}

How can I solve this?


Solution

  • What it meant is that you need to save the stream to a variable and then use it in a try-with-resources or close it in a try-finally. So either this:

    try (Stream<Path> paths = Files.walk(Paths.get(ifRecordsPath))) {
        paths.filter(Files::isDirectory)
            .map(ifRecordsCollector)
            .map(ifRecordStreamAccumulator)
            .forEach(ifRecordCollection::addAll);
        return ifRecordCollection;
    }
    

    Or this:

    Stream<Path> paths = Files.walk(Paths.get(ifRecordsPath));
    try {
        paths.filter(Files::isDirectory)
            .map(ifRecordsCollector)
            .map(ifRecordStreamAccumulator)
            .forEach(ifRecordCollection::addAll);
        return ifRecordCollection;
    } finally {
        paths.close();
    }