通过扫描文件系统查找直接和间接子类
我在编写算法以帮助我扫描文件系统并查找某个类的所有子类时遇到问题。
详:
我有一个应用程序,它扫描外部应用程序,在检索时使用,我在读取文件时检查“扩展超类”,如果单词退出,我将类名添加到我的列表中,如下所示:nio
Files.walk()
List<String> subclasses = new ArrayList<>();
Files.walk(appPath)
.filter(p->Files.isRegularFile(p) && p.toString()
.endsWith(".java")).forEach(path -> {
try {
List<String> lines = Files.readAllLines(path);
Pattern pattern = Pattern.compile("\\bextends SuperClass\\b");
Matcher matcher = pattern
.matcher(lines.stream()
.collect(Collectors.joining(" ")));
boolean isChild = matcher.find();
if(isChild) subclasses.add(path.getFileName().toString());
}catch (IOException e){
//handle IOE
}
上面的问题是它只得到的直接子类,但我需要检索所有直接和间接子类。我想到了递归,因为我不知道有多少子类,但我无法实现任何合理的实现。SuperClass
SuperClass
笔记:
- 扫描超过60万个文件
- 我不知道有多少个直接/间接的子类
SuperClass
- 我正在扫描的应用程序是外部的,我无法修改其代码,因此我只能通过读取文件并查看存在的位置来访问它
extends
- 如果有一个非递归的解决方案来解决这个问题,那就太好了,但是如果没有其他方法,我将非常乐意接受递归解决方案,因为我更关心解决方案而不是性能。
编辑:
我使用以下正则表达式来比较名称和导入,以确保即使在同名不同包的情况下,输出也是正确的:
Pattern pattern = Pattern.compile("("+superClasss.getPackage()+")[\\s\\S]*(\\bextends "+superClass.getName()+"\\b)[\\s\\S]");
我还尝试了:
Pattern pattern = Pattern.compile("\\bextends "+superClass.getName()+"\\b");
但是也有一些缺少的子类,我相信下面的代码跳过了一些检查,并且不能完全工作:
public static List<SuperClass> getAllSubClasses(Path path, SuperClass parentClass) throws IOException{
classesToDo.add(baseClass);
while(classesToDo.size() > 0) {
SuperClass superClass = classesToDo.remove(0);
List<SuperClass> subclasses = getDirectSubClasses(parentPath,parentClass);
if(subclasses.size() > 0)
classes.addAll(subclasses);
classesToDo.addAll(subclasses);
}
return classes;
}
任何帮助真的非常感谢!
编辑 2我还注意到另一个问题是,当我检测到一个时,我得到的文件名可能是也可能不是子类名称,因为子类可能是同一文件中的或非公共的。subclass
currentPath.getFileName()
nested
class