Как защитить Files.walk от репликации символических ссылок? Использование Java или оболочки.Как защитить Files.walk от репликации символических ссылок?
ответ
Хорошо, поэтому следуйте ссылкам.
Stream<Path> stream = walk(startPath, maxDepth, FileVisitOption.FOLLOW_LINKS);
Однако проверять каждый каталог, является ли это символическая ссылка:
Files.isSymbolicLink(path) && Fles.isDirectory(path)
Использование
Path realPath = path.toRealPath();
Затем, сохраняя список каталогов на в, предков, можно было бы предотвратить рекурсию. Делая для каждый каталог, проверяющий предков, когда символическая ссылка находится где-то в списке/текущем пути.
a > b > START:c > d > e > SYMBOLIC:f=a > b > c
(Это еще не мешает посетить каталог в два раза, как то же самое или поддиректории может быть связано без рекурсии.)
Вы можете параметризовать вызов Files.walk
с помощью FileVisitOption
.
Если вы не добавили FileVisitOption.FOLLOW_LINKS
, сканирование не будет следовать символическим ссылкам.
См. API here.
Files.walk
не кажется, защищаемые для символической рекурсии ссылки. Вы можете ограничить глубину поиска, установив maxDepth
на что-то разумное, например i.d.k. 200 иш?
Если вам нужен более надежный метод, чем произвольное ограничение глубины, вы можете реализовать FileVisitor
, который, когда он сталкивается с символической ссылкой, проверяет, является ли он рекурсивным, а затем решает, хотите ли вы следовать ему или нет. Затем используйте посетителя с Files.walkFileTree
. Однако это не даст вам приятного потока путей, поэтому вам, вероятно, придется внести некоторые изменения в свой код.
Что касается обнаружения символических ссылок, которые являются рекурсивными, я думаю, что вы можете сделать колдовство с помощью File.getCanonicalPath
и хеш-карту посещенных канонических путей. У меня нет операционной системы Linux, поэтому я не тестировал это, хотя, YMMV.
Независимо от того, что вы делаете, не используйте List
посещенных путей, как предлагают другие ответы, так как это даст вам время O (n²) для итерации по файловой системе.
Спасибо! Но если мне нужно посетить символические ссылки, которые не приводят к рекурсии? – Arthur
@Arthur Я не думаю, что там было бы или должно быть Java-решение. Это потребует, чтобы Java-процесс заранее обнаружил, является ли символическая ссылка рекурсивной и прекращает сканирование там. – Mena