I have the following method to retrieve the names of a logfiles produced by logback in a log directory. The first 9 lines determine the logging directory:
private List<String> getLogFileNames() {
List<String> logFileNames = new ArrayList<>();
ch.qos.logback.classic.Logger rootLogger = ((ch.qos.logback.classic.Logger) LOGGER).getLoggerContext().getLogger("root");
Path logDir;
Appender<ILoggingEvent> appender = rootLogger.getAppender("file");
if (appender == null) {
logDir = Paths.get(System.getProperty("user.dir"), "../logs");
} else {
RollingFileAppender<?> rollingFileAppender = (RollingFileAppender<?>) appender;
logDir = Paths.get(rollingFileAppender.getFile()).getParent();
}
try {
Files.list(logDir).forEach(log -> logFileNames.add(log.toFile().getName()));
} catch (IOException e) {
throw new IllegalStateException(e);
}
return logFileNames;
}
Sometimes the following exception is thrown: java.nio.file.FileSystemException: ... : Too many open files
I suspect the exception is thrown in the Files.list(logDir).forEach() statement. Somehow in this piece of code files are being opened but never closed. How should I solve this? Can I use a foreach statement or should I use something like:
try(Stream<Path> stream = Files.walk(logDir)) {
// Code to extract the filename
}
catch(UncheckedIOException ex) {
throw ex.getCause();
}
Duplicate: Why does usage of java.nio.files.File::list is causing this breadth-first file traversal program to crash with the "Too many open files" error?
Consider using the Try With Resources Approach.