Начиная с Java 8, вы можете сделать это в три строки:
try (Stream<Path> files = Files.list(Paths.get("your/path/here"))) {
long count = files.count();
}
Относительно 5000 дочерних узлов и аспектов inode:
Этот метод будет перебирать записи, но, как предположил Вархан, вы, вероятно, не добьетесь большего успеха, чем играя с JNI или прямыми вызовами системных команд, но даже тогда вы никогда не сможете быть уверены, что эти методы не делают одно и то же!
Однако давайте немного углубимся в это:
Глядя на источник JDK8, Files.list
предоставляет поток , который использует Iterable
из Files.newDirectoryStream
, который делегирует FileSystemProvider.newDirectoryStream
.
В системах UNIX (декомпилировано sun.nio.fs.UnixFileSystemProvider.class
) загружается итератор: используется sun.nio.fs.UnixSecureDirectoryStream
(с блокировками файлов во время итерации по каталогу).
Итак, есть итератор, который будет проходить здесь все записи.
Теперь давайте посмотрим на механизм подсчета.
Фактический подсчет выполняется API уменьшения подсчета / суммы, выставляемого потоками Java 8 . Теоретически этот API может выполнять параллельные операции без особых усилий (с многопоточностью). Однако поток создается с отключенным параллелизмом, поэтому он не нужен ...
Хорошая сторона этого подхода заключается в том, что не будет загружать массив в память , поскольку записи будут подсчитываться итератором, поскольку они читаются базовым (файловая система ) API.
Наконец, для информации, концептуально в файловой системе, узел каталога не обязан хранить число файлов, которые он содержит, он может просто содержать список это дочерние узлы (список инодов). Я не эксперт по файловым системам, но я считаю, что файловые системы UNIX работают именно так. Таким образом, вы не можете предполагать, что есть способ получить эту информацию напрямую (т.е. всегда может быть где-то скрыт какой-то список дочерних узлов).