Ответ 1
Я столкнулся с той же проблемой (в Windows Server 2012 R2), когда я не закрыл поток. Все файлы, которые я повторил, были открыты в режиме чтения, пока JVM не был отключен. Однако это не произошло в Mac OS X, и поскольку поток зависит от OS-зависимых реализаций FileSystemProvider
и DirectoryStream
, я предполагаю, что проблема также может быть зависимой от ОС.
В отличие от комментария @Ian McLaird, он упоминается в Files.list()
документации, которая
Если требуется своевременное удаление ресурсов файловой системы, следует использовать конструкцию try-with-resources для обеспечения того, чтобы метод закрытия потока был вызван после завершения операций потока.
Возвращенный поток - это DirectoryStream
, чей Javadoc говорит:
DirectoryStream открывается при создании и закрывается вызовом метода close. Закрытие потока каталога освобождает любые ресурсы, связанные с потоком. Невозможность закрыть поток может привести к утечке ресурса.
Мое решение состояло в том, чтобы следовать совету и использовать конструкцию try-with-resources
try (Stream<Path> fileListing = Files.list(directoryPath)) {
// use the fileListing stream
}
Когда я правильно закрыл поток (использовал выше конструкцию try-with-resources
), дескрипторы файлов были немедленно выпущены.
Если вы не хотите получать файлы в виде потока, или вы в порядке с загрузкой всего списка файлов в память и преобразованием его в поток самостоятельно, вы можете использовать IO API:
File directory = new File("/path/to/dir");
File[] files = directory.listFiles();
if (files != null) { // 'files' can be null if 'directory' "does not denote a directory, or if an I/O error occurs."
// use the 'files' array or convert to a stream:
Stream<File> fileStream = Arrays.stream(files);
}
У меня не было проблем с блокировкой файлов с этим. Однако обратите внимание, что оба решения зависят от собственного, зависящего от ОС кода, поэтому я советую тестировать во всех средах, которые вы использовали.