If you want to log all files of the either category together, there is no way around collecting them into a data structure holding them, until all elements are known. Still, you can simplify your code:
Stream.of(tmpDir.listFiles()) .filter(tempFile -> tempFile.getName().endsWith(".csv")) .collect(Collectors.partitioningBy(File::delete, Collectors.mapping(File::getAbsolutePath, Collectors.joining(",")))) .forEach((success, files) -> { if (!files.isEmpty()) { LOGGER.debug(success? "deleted temporary files, {}": "failed to delete temporary files, {}", files); } });
This doesn’t collect the files into a List but into the intended String for the subsequent logging action in the first place. The logging action also is identical for both cases, but only differs in the message.
Still, the most interesting thing is why deleting a file failed, which a boolean doesn’t tell. Since Java 7, the nio package provides a better alternative:
Create helper method
public static String deleteWithReason(Path p) { String problem; IOException ioEx; try { Files.delete(p); return ""; } catch(FileSystemException ex) { problem = ex.getReason(); ioEx = ex; } catch(IOException ex) { ioEx = ex; problem = null; } return problem!=null? problem.replaceAll("\\.?\\R", ""): ioEx.getClass().getName(); }
and use it like
Files.list(tmpDir.toPath()) .filter(tempFile -> tempFile.getFileName().toString().endsWith(".csv")) .collect(Collectors.groupingBy(YourClass::deleteWithReason, Collectors.mapping(p -> p.toAbsolutePath().toString(), Collectors.joining(",")))) .forEach((failure, files) -> LOGGER.debug(failure.isEmpty()? "deleted temporary files, {}": "failed to delete temporary files, "+failure+ ", {}", files) );
The disadvantage, if you want to call it that way, is does not produce a single entry for all failed files, if they have different failure reasons. But that’s obviously unavoidable if you want to log them with the reason why they couldn’t be deleted.
Note that if you want to exclude “being deleted by someone else concurrently” from the failures, you can simply use Files.deleteIfExists(p) instead of Files.delete(p) and being already deleted will be treated as success.
map. Or, if you really want, usepartition.