查找文件夹下所有文本是否包含了特定的字符串, 如果包含了, 就打印文件的全路径.为啥需要这个功能, 其实是为了查找有哪些controller中提供的方法是没有被用到的. 有了这个工具类就不用一个项目一个项目的去搜索了.直接用线程池全量搜索.
依赖于apache的lang3和google的guava的包
import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 寻找一个文件夹下所有的以.java结尾的文件中, 是否包含 特定的内容 * * @author zhangke * @time 2020年10月20日15:17:05 */ public class FinderUtil { /** * 要查找的内容 */ private static String searchContext = "CarOwnerInfo"; /** * 使用一个大小为100的线程池 */ private static ExecutorService service = Executors.newFixedThreadPool(100); public static void main(String[] args) throws InterruptedException { getFiles(Lists.newArrayList("D:\\workspace")); TimeUnit.SECONDS.sleep(15); service.shutdown(); } /** * 遍历一个文件中所有的行, 是否包含要查找的字符串 */ public static void findString(String path) { //先判断文件是否是以.java结尾的,或者.xml结尾的,不是就不需要判断了 if (!StringUtils.endsWith(path, ".java") && !StringUtils.endsWith(path, ".xml")) { return; } File file = new File(path); //文件为空,直接返回 if (!file.exists()) { return; } try { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file), "UTF-8"); BufferedReader reader = new BufferedReader(inputStreamReader); // 按行读取字符串 String line; while ((line = reader.readLine()) != null) { if (StringUtils.contains(line, searchContext)) { System.out.println("当前的文件名是:" + path); //找到了就退出 break; } } reader.close(); inputStreamReader.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 递归获取某路径下的所有文件,文件夹 */ public static void getFiles(List<String> paths) { //遍历路径 for (String path : paths) { service.submit(() -> { File file = new File(path); // 如果这个路径是文件夹 if (file.isDirectory()) { // 获取路径下的所有文件 File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { // 如果还是文件夹 递归获取里面的文件 文件夹 if (files[i].isDirectory()) { getFiles(Lists.newArrayList(files[i].getPath())); } else { //是文件,直接去查找 String absolutePath = files[i].getAbsolutePath(); findString(absolutePath); } } } else { //是文件,直接去查找 String absolutePath = file.getAbsolutePath(); findString(absolutePath); } }); } } }
然而我同事自己写的另外一套, 更加的自动化
import java.util.Objects; /** * @author dengfengfeng * @date 2020/10/20 */ public class FormatOutput { private String projectName; private String className; private String methodName; private String methodMapping; public String getProjectName() { return projectName; } public void setProjectName(String projectName) { this.projectName = projectName; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } public String getMethodMapping() { return methodMapping; } public void setMethodMapping(String methodMapping) { this.methodMapping = methodMapping; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FormatOutput that = (FormatOutput) o; return Objects.equals(methodMapping, that.methodMapping); } @Override public int hashCode() { return Objects.hash(methodMapping); } @Override public String toString() { return "FormatOutput{" + "projectName='" + projectName + '\'' + ", className='" + className + '\'' + ", methodName='" + methodName + '\'' + ", methodMapping='" + methodMapping + '\'' + '}'; } } import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * @author dengfengfeng * @date 2020/10/19 */ public class FindInvalidProvider { private final static String projectPath = "C:\\Users\\82419\\IdeaProjects"; private final static String feignClient = "${customer.feign.name}"; private final static Pattern requestBasePath = Pattern.compile("@RequestMapping\\(\"(.*)\"\\)"); private final static Pattern mappingPath = Pattern.compile("Mapping\\(\"(.*)\"\\)"); private final static Vector<FormatOutput> pathList = new Vector<>(); private static List<String> ps = new ArrayList<>(); private final FileFilter javaFileFilter = f -> isJavaFile(f); private final static String srcCodeDirectory = projectPath +File.separator+ "crm-service\\customer-service\\src\\main\\java\\com\\ydcloud\\customer\\controller\\provider"; public static void main(String[] args) { //首先确定需要分析的项目的地址 File file = new File(srcCodeDirectory); System.out.println(file.getAbsolutePath()); extractAllMappingToVector(file); System.err.println("一共"+pathList.size()+"个接口"); System.out.println("所有的provider"); System.out.println(pathList); ps = pathList.stream().map(FormatOutput::getMethodMapping).collect(Collectors.toList()); //检查其他项目有没有调用目标服务 File root = new File(projectPath); excludeMapping(root); System.err.println("剩下的provider"); System.err.println(pathList); System.err.println("一共"+pathList.size()+"个接口未被使用"); System.err.println("格式化输出"); pathList.forEach( p->{ String methodMapping = p.getMethodMapping(); String className = p.getClassName(); String substring = methodMapping.substring(9); System.err.println(className+","+substring); } ); } private static boolean isJavaFile(File file) { if (file.exists() && !file.isDirectory()) { int lastIndexOf = file.getName().lastIndexOf("."); if (lastIndexOf == -1) { return false; } String suffix = file.getName().substring(lastIndexOf); return ".java".equals(suffix); } else { return false; } } private static void excludeMapping(File file) { if (file.exists()) { if (file.isDirectory()) { if (file.getAbsolutePath().contains("crm-service\\customer-service")) { return; } File[] files = file.listFiles(); for (File f : files) { excludeMapping(f); } } else { if (isJavaFile(file)) { try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file)); BufferedReader reader = new BufferedReader(isr);) { String tmp; String basePath = ""; boolean isFeignClient = false; while ((tmp = reader.readLine()) != null) { if (!isFeignClient) { isFeignClient = getFeignClient(tmp); } // 处理读取的数据 if (basePath.equals("")) { basePath = findMappingValue(tmp, requestBasePath); } else { String mappingValue = findMappingValue(tmp, mappingPath); if (!mappingValue.equals("")) { String path = basePath + mappingValue; path = path.replace("//", "/"); FormatOutput formatOutput = new FormatOutput(); formatOutput.setMethodMapping(path); if (pathList.contains(formatOutput)) { if(isFeignClient){ pathList.remove(formatOutput); } } } } } } catch (IOException e) { e.printStackTrace(); } } } } } private static void extractAllMappingToVector(File file) { if (file.exists()) { if (file.isDirectory()) { File[] files = file.listFiles(); for (File f : files) { extractAllMappingToVector(f); } } else { if (isJavaFile(file)) { try (InputStreamReader isr = new InputStreamReader(new FileInputStream(file)); BufferedReader reader = new BufferedReader(isr);) { String tmp; String basePath = ""; while ((tmp = reader.readLine()) != null) { // 处理读取的数据 if (basePath.equals("")) { basePath = findMappingValue(tmp, requestBasePath); } else { String mappingValue = findMappingValue(tmp, mappingPath); if (!mappingValue.equals("")) { String path = basePath + mappingValue; path = path.replace("//", "/"); FormatOutput formatOutput = new FormatOutput(); formatOutput.setClassName(file.getName()); formatOutput.setMethodMapping(path); pathList.add(formatOutput); } } } } catch (IOException e) { e.printStackTrace(); } } } } } private static String findMappingValue(String line, Pattern pattern) { Matcher matcher = pattern.matcher(line); if (matcher.find()) { return matcher.group(1); } else { return ""; } } private static boolean getFeignClient(String line) { if (line.contains(feignClient)) { return true; } else { return false; } } }他这个就是专门查找controller中的, 有没有这个controller有没有被用到的, 功能更加的单一.
至于孰优孰劣的问题, 就不说了, 因为考虑的场景不同, 我做的更加通用一些, 相当于半自动化的, 他写的是全自动化, 只能做这一块的功能.