Last active
June 4, 2018 21:05
-
-
Save jamesdaily/2f938b52235b400089d96e8ea248b8ae to your computer and use it in GitHub Desktop.
Example of Files.list() resource leaks for Spot Bugs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.jamesdaily.spotbugs.FileDescriptorLeak; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.util.stream.Stream; | |
public class FilesListExample { | |
/* | |
* SpotBugs should detect and warn about the unclosed input stream created | |
* by Files.list(). | |
* | |
* https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#list-java.nio.file.Path- | |
* | |
* "The returned stream encapsulates a DirectoryStream. If timely disposal | |
* of file system resources is required, the try-with-resources construct | |
* should be used to ensure that the stream's close method is invoked after | |
* the stream operations are completed." | |
* | |
*/ | |
public static void main(String[] args) { | |
final String dir = "./"; | |
System.out.println("Starting processFilesFluidForEach()..."); | |
processFilesFluidForEach(dir); | |
System.out.println("Starting processFilesExplicitStream()..."); | |
processFilesExplicitStream(dir); | |
System.out.println("Starting processFilesExplicitStreamTryWithResources()..."); | |
processFilesExplicitStreamTryWithResources(dir); | |
} | |
/** | |
* Compiler/IDE helpfully warns: "Resource leak: 'files' is never closed" | |
*/ | |
private static void processFilesExplicitStream(String pathdir) { | |
Path path = Paths.get(pathdir); | |
try { | |
Stream<Path> files = Files.list(path); | |
files.forEach(System.out::println); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* Compiler/IDE fails to warn. | |
* Files.list(path) Stream is never closed | |
* (.forEach() does not close it) | |
*/ | |
private static void processFilesFluidForEach(String pathdir) { | |
Path path = Paths.get(pathdir); | |
try { | |
Files.list(path).forEach(System.out::println); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* No warning needed, since Stream is auto-closed via try-with-resources | |
*/ | |
private static void processFilesExplicitStreamTryWithResources(String pathdir) { | |
Path path = Paths.get(pathdir); | |
try (Stream<Path> files = Files.list(path)) { | |
files.forEach(System.out::println); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment