LIXIFUN - Path.endswith() 的是 Path 不是文件名后缀
假设有这样一个需求,删除某一个目录下的 “.json” 结尾的,修改时间在 x 分钟之前的文件。
public class Solution {
public static void main(String[] args) {
delete(Path.of("/home/lixifun/log"), ".json", 30, TimeUnit.MINUTES);
}
private static void delete(Path dir, String suffix, int time, TimeUnit timeUnit) {
Instant timeNodeToDelete = Instant.now().minusMillis(timeUnit.toMillis(time));
DirectoryStream.Filter<Path> filter = file -> {
Instant fileLastModTime = Files.getLastModifiedTime(file).toInstant();
// 问题就出现在下面两句了
// 注释掉的是不正确的
// return file.endsWith(suffix)
// && fileLastModTime.isBefore(timeNodeToDelete);
// 这个是正确的
return file.toString().endsWith(suffix)
&& fileLastModTime.isBefore(timeNodeToDelete);
};
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dir, filter)) {
for (Path file : dirStream) {
Files.delete(file);
}
} catch (IOException e) {
e.printStackTrace();
}
}
主要问题就在 Path.endswith()
不是用来匹配后缀的,是用来匹配 Path
的,仅仅一个后缀 不能 表示一个 Path
。
public class PathTest {
public static void main(String[] args) {
Path aLog = Path.of("/home/lixifun/log/log1.json");
System.out.println(aLog.endsWith("json")); // false
System.out.println(aLog.endsWith(".json")); // false
System.out.println(aLog.endsWith("1.json")); // false
System.out.println(aLog.endsWith("log1.json")); // true
System.out.println(aLog.endsWith("/log1.json")); // false
System.out.println(aLog.endsWith("log/log1.json")); // true
}
}
通过示例可以看出只有在完全匹配文件名或某个相对路径(不带.)时才匹配。
通过查看源码 Path.endswith(String)
调用的是 Path.endswith(Path)
也就是说 String
类型仅仅是作为字面量来表示某个 Path
的,实际匹配的是 Path
。