我正在尝试研究 newDirectoryStream
的 DirecoryStream.Filter
示例,我可以在其中列出目录下的所有文件(及其所有子目录) 超过 60 天,例如。
DirectoryStream<Path> dirS = Files.newDirectoryStream(Paths.get("C:/myRootDirectory"), <DirectoryStream.filter>);
for (Path entry: dirS) {
System.out.println(entry.toString());
}
在上面的代码中,DirectoryStream.filter
应该是什么?
这将是一个很大的帮助,因为我在一个项目中,我试图删除早于某个时间戳的文件,而 Java 1.7 之前的 File.listFiles()
只是挂起。
Files.walkFileTree()
可以提供一个选项吗?
最佳答案
如果我做对了,你有两种情况:
- 创建自定义
过滤器
以选择超过 60 天的文件 - 遍历子目录(整个
FileTree
)并收集您的信息
使用 Calendar
类实现的 60 天条件更易于实现自定义过滤器:
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {BasicFileAttributes attr = Files.readAttributes(entry,BasicFileAttributes.class);
FileTime creationTime = attr.creationTime();
Calendar cal = Calendar.getInstance();
int days = cal.fieldDifference(new Date(creationTime.toMillis()),Calendar.DAY_OF_YEAR);
return (Math.abs(days) > 60);
}
};
正常执行只会查找根目录下的文件。要查找子目录,您对使用 walkFileTree()
的猜测是正确的。
但是,这需要实现 FileVisitor
接口(interface),幸运的是,它的一个简单实现与 7 - SimpleFileVisitor
捆绑在一起。
要遍历子目录,您可以选择覆盖目录特定方法 - 我在这里使用了 SimpleFileVisitor
的 preVisitDirectory
:
Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path file,
BasicFileAttributes attrs) {
由于 preVisitDirectory
将被定制为 return FileVisitResult.CONTINUE;
如果您没有任何额外的限制,我们将利用 preVisitDirectory
在应用过滤器时一次遍历目录 1 的方法。
Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path file,
BasicFileAttributes attrs) {
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
BasicFileAttributes attr = Files.readAttributes(entry,
BasicFileAttributes.class);
FileTime creationTime = attr.creationTime();
Calendar cal = Calendar.getInstance();
int days = cal.fieldDifference(
new Date(creationTime.toMillis()),
Calendar.DAY_OF_YEAR);
return (Math.abs(days) > 60);
}
};
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
file, filter)) {
for (Path path : stream) {
System.out.println(path.toString());
}
} catch (IOException ex) {
ex.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
这将为您提供所需过滤条件的整个目录和子目录结构中的文件,下面是完整的主要方法:
public static void main(String[] args) throws IOException {
Path dirs = Paths.get("C:/");
Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path file,
BasicFileAttributes attrs) {
DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
BasicFileAttributes attr = Files.readAttributes(entry,
BasicFileAttributes.class);
FileTime creationTime = attr.creationTime();
Calendar cal = Calendar.getInstance();
int days = cal.fieldDifference(
new Date(creationTime.toMillis()),
Calendar.DAY_OF_YEAR);
return (Math.abs(days) > 60);
}
};
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
file, filter)) {
for (Path path : stream) {
System.out.println(path.toString());
}
} catch (IOException ex) {
ex.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
}
关于java - 用于列出基于特定日期/时间的文件的 DirectoryStream.Filter 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21733390/