#java #spring
Вопрос:
У меня есть регулярное выражение( это регулярное выражение не является статическим, а вводится из конфигурации — может быть любым допустимым регулярным выражением), и мне нужно найти все файлы, соответствующие этому регулярному выражению.
Пример регулярного выражения /home/users/[a-zA-Z] /[a-z].png
До сих пор я использую:
Files.walkFileTree(Paths.get("/"), Collections.emptySet(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
try {
File f = file.toFile();
String absoluteFileName = f.getAbsolutePath().replace("\", "/").replace("C:", "");
Matcher m = p.matcher(absoluteFileName);
if (m.matches()) {
files.add(f.getAbsolutePath());
}
return FileVisitResult.CONTINUE;
} catch (Exception e) {
return FileVisitResult.SKIP_SUBTREE;
}
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
LOGGER.error(String.format("Error visiting %s exception: %s", file, exc));
if (!(exc instanceof AccessDeniedException)) {
throw exc;
}
return FileVisitResult.CONTINUE;
}
});
Это действительно находит все файлы, соответствующие регулярному выражению, однако это слишком медленно и не очень эффективно. Есть ли лучший, более эффективный способ найти эти файлы? Я открыт для внешних библиотек
Комментарии:
1. Разделение регулярного выражения на файл.разделитель позволит вам просматривать меньше каталогов, но это может быть проблематично, так как символ может находиться внутри классов символов, поисков, части чередования и т. Д.
2. Если у вас есть свобода изменять формат шаблона ввода, рассмотрите возможность использования списка регулярных выражений (по одному на уровень вложенности каталога). Таким образом, вы можете на каждом уровне ограничить подкаталоги для поиска теми, которые до сих пор соответствуют шаблону.
3. @Аарон, не могли бы вы поподробнее, пожалуйста?
4. Ваше решение работает медленно, потому что оно проверяет каждый отдельный файл в вашей системе. Он должен понимать, что поиск файла
/a/b/c
внутри/x/
-пустая трата времени и что он не должен пересекать содержимое этого каталога. Но вам нужен способ выяснить на каждом уровне, находятся ли подкаталоги «в правильном направлении». Если ваше входное регулярное/a/b/c
выражение такое же, как в моем предыдущем примере, это просто : разделите его на/
три части, используйте три результирующие части в качестве регулярных выражений, пока вы спускаетесь по дереву файлов. Но регулярные выражения могут использоваться/
в других контекстах, например,/[^/]*/
или(/a/b|/b/c)
там, где разделение не будет работать5. Поэтому я предлагаю вам изменить формат ввода с одного регулярного выражения (например
/home/users/[a-zA-Z] /[a-z].png
) на регулярное выражение для каждого каталога (например/home, /users, /[a-zA-Z] , /[a-z].png
, возможно, без косых черт), которое вы бы сопоставляли по одному при спуске по дереву файлов