Groovy遍历目录时排除指定文件的代码问题及解决方案
问题:Groovy目录搜索排除指定文件失效及解决方案
问题描述
我需要在指定目录的所有文件中搜索指定关键词,但需排除terminal.log文件。当前Groovy代码中,if(!file2_path == terminal_log_path)这段排除逻辑无法正常工作,请求修正方案,同时希望了解Groovy遍历目录时排除指定文件的相关用法。
用户输入示例:search test C:\Users\Desktop\test\Groovy
原代码:
import static groovy.io.FileType.FILES import java.text.SimpleDateFormat def terminal_log = new File("terminal.log") def terminal_log_path = terminal_log.getName() def fas = "" def file2_path = "" def cmd = System.console().readLine 'Enter command: ' String[] csplice = cmd.split(" "); if(csplice.length == 3){ def first_parameter = csplice[0] def second_parameter = csplice[1] def third_parameter = csplice[2] if(first_parameter == "search"){ def file = new File(third_parameter) if(file.exists()){ if(file.isDirectory()){ file.eachFile(FILES) { f -> fas = "/"+f+"/" File file2 = new File(fas) file2_path = file2.getName() if(!file2_path == terminal_log_path){ file2.eachLine{ line -> if(line.contains(second_parameter)){ println "This file contains this word" } } } } }else{ println "Not a directory" } }else{ println "Not exists" } }else{ println "Invalid command" } }else{ println "Invalid command" }
错误原因分析
- 逻辑运算符优先级错误:
!file2_path == terminal_log_path会先执行!file2_path(非空字符串取反结果为false),再和文件名比较,永远无法触发排除逻辑。正确的判断应为!(file2_path == terminal_log_path)或file2_path != terminal_log_path。 - 冗余文件对象创建:
fas = "/"+f+"/"和File file2 = new File(fas)完全多余,eachFile闭包中的f已经是当前遍历到的File对象,直接调用f.getName()即可获取文件名。
修正后的代码
import static groovy.io.FileType.FILES def excludedFileName = "terminal.log" def cmd = System.console().readLine 'Enter command: ' String[] csplice = cmd.split(" "); if(csplice.length == 3 && csplice[0] == "search"){ def keyword = csplice[1] def targetDir = new File(csplice[2]) if(!targetDir.exists()){ println "Not exists" return } if(!targetDir.isDirectory()){ println "Not a directory" return } targetDir.eachFile(FILES) { file -> if(file.getName() != excludedFileName){ file.eachLine{ line -> if(line.contains(keyword)){ println "File ${file.absolutePath} contains the keyword" } } } } }else{ println "Invalid command" }
Groovy遍历目录排除文件的常用方法
- 闭包内直接判断:使用
eachFile/eachFileRecurse遍历目录时,可直接通过File对象的name属性判断是否需要排除文件,如上述修正代码中的写法。 - 自定义FileFilter:若需要更复杂的过滤规则,可使用
File.listFiles(FileFilter)方法,通过匿名内部类实现过滤逻辑:def filter = new FileFilter() { boolean accept(File f) { return !f.name.equals("terminal.log") && f.isFile() } } targetDir.listFiles(filter).each { file -> // 执行文件处理逻辑 } - 利用Groovy简化语法:Groovy的
File类扩展了JDK的File,所有JDK文件过滤方法都可直接使用,结合闭包能进一步简化代码,比如用闭包替代FileFilter:targetDir.eachFile(FILES) { file -> if(!file.name in ["terminal.log", "temp.txt"]){ // 多文件排除逻辑 } }
内容的提问来源于stack exchange,提问作者bjhayeyy
相关产品推荐
相关产品推荐

