Java中文件名过滤器:包含多扩展名或排除指定文件类型
解决方案:日志文件列表展示优化
首先先贴出你当前的Controller方法代码:
private String[] getFileListing(String servers) throws IOException { Properties prop = new Properties(); String propFileName = "config.properties"; InputStream input = getClass().getClassLoader().getResourceAsStream(propFileName); prop.load(input); if (servers.equals("MS1")) { File f = new File(prop.getProperty("path.MS1")); String[] list = f.list(new FilenameFilter() { public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(".txt")||name.endsWith(".log"); } }); return list; } else { File f = new File(prop.getProperty("path.MS2")); String[] list = f.list(new FilenameFilter() { public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(".txt")||name.endsWith(".log"); } }); return list; } }
问题1:纳入带.1、.2等后缀的日志文件
当然有简便方法!咱们可以用正则表达式来匹配文件名,既能覆盖.txt/.log,也能匹配比如app.log.1、error.txt.2这类带数字后缀的文件。
修改FilenameFilter的accept方法,用正则匹配文件名的模式:
public boolean accept(File dir, String name) { // 匹配:以.txt或.log结尾,或者以.log.数字、.txt.数字结尾的文件 return name.matches(".*\\.(txt|log)(\\.\\d+)?$"); }
解释一下这个正则:
.*:匹配文件名开头的任意字符\\.(txt|log):匹配.txt或.log后缀(\\.\\d+)?:可选部分,匹配.1、.23这类数字后缀(?表示这部分可以有也可以没有)$:匹配字符串结尾,确保后缀是在文件名最后
如果你想忽略大小写(比如匹配.TXT.1),可以把正则改成(?i).*\\.(txt|log)(\\.\\d+)?$,或者用更直观的写法:
public boolean accept(File dir, String name) { String lowerName = name.toLowerCase(); return lowerName.endsWith(".txt") || lowerName.endsWith(".log") || lowerName.matches(".*\\.(txt|log)\\.\\d+$"); }
问题2:展示除指定类型外的所有文件(排除系统文件)
这个需求刚好反过来,我们只需要在accept方法里排除掉不需要的文件类型就行。比如你要排除.swp、.tmp、.bak这类系统生成的文件,可以这么写:
public boolean accept(File dir, String name) { String lowerName = name.toLowerCase(); // 排除指定的系统文件类型,返回剩下的所有文件 return !lowerName.endsWith(".swp") && !lowerName.endsWith(".tmp") && !lowerName.endsWith(".bak"); }
如果要排除的类型比较多,也可以把它们放到一个集合里,维护起来更方便:
public boolean accept(File dir, String name) { Set<String> excludedExts = new HashSet<>(Arrays.asList(".swp", ".tmp", ".bak")); String lowerName = name.toLowerCase(); // 检查文件名的后缀是否在排除集合中 for (String ext : excludedExts) { if (lowerName.endsWith(ext)) { return false; } } return true; }
要是你还想排除特定系统文件名(比如.DS_Store、Thumbs.db),直接加判断即可:
public boolean accept(File dir, String name) { return !name.equals(".DS_Store") && !name.equals("Thumbs.db") && !name.toLowerCase().endsWith(".swp"); }
额外优化:避免重复代码
你当前代码里MS1和MS2的逻辑几乎完全一致,只是路径不同。可以把这部分逻辑抽成统一的方法,减少重复:
private String[] getFileListing(String servers) throws IOException { Properties prop = new Properties(); String propFileName = "config.properties"; InputStream input = getClass().getClassLoader().getResourceAsStream(propFileName); prop.load(input); // 根据服务器获取对应路径 String path = servers.equals("MS1") ? prop.getProperty("path.MS1") : prop.getProperty("path.MS2"); File f = new File(path); // 调用统一的文件过滤方法 return f.list(new FilenameFilter() { public boolean accept(File dir, String name) { // 这里放你选择的过滤逻辑(问题1或问题2的实现) return name.matches(".*\\.(txt|log)(\\.\\d+)?$"); } }); }
这样以后修改过滤逻辑只需要改一处就行,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Niharika Pandey
相关产品推荐
相关产品推荐

