我正在尝试调查DirecoryStream.Filter
的{{1}}示例,我可以在其中列出早于目录的所有文件(及其所有子目录)以60天为例。
newDirectoryStream
在上面的代码中,DirectoryStream<Path> dirS = Files.newDirectoryStream(Paths.get("C:/myRootDirectory"), <DirectoryStream.filter>);
for (Path entry: dirS) {
System.out.println(entry.toString());
}
应该是什么?
这将是一个很好的帮助,因为我在一个项目中,我试图删除早于某个时间戳的文件,并且java-{1.7}之前的文件只是挂起。
可以DirectoryStream.filter
提供选项吗?
答案 0 :(得分:7)
如果我做对了,你有两种情况:
filter
以选择超过60天的文件FileTree
)并收集您的信息使用Calendar
类:
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
接口,这是一个简单的实现,幸运的是与7 - SimpleFileVisitor
捆绑在一起。
要遍历子目录,您可以选择覆盖特定于目录的方法 - 我在preVisitDirectory
使用了SimpleFileVisitor
:
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;
}
});
}
答案 1 :(得分:3)
如果给定的DirectoryStream.Filter
对象超过60天,只需创建一个返回true
的新Path
实例。
DirectoryStream<Path> dirStream = Files.newDirectoryStream(Paths.get("/some/path"), new Filter<Path>() {
@Override
public boolean accept(Path entry) throws IOException {
FileTime fileTime = Files.getLastModifiedTime(entry);
long millis = fileTime.to(TimeUnit.MILLISECONDS);
Calendar today = Calendar.getInstance();
// L is necessary for the result to correctly be calculated as a long
return today.getTimeInMillis() > millis + (60L * 24 * 60 * 60 * 1000);
}
});
请注意,这只会为您提供指定目录Path
的根目录内的文件,即。 Path
参数传递给newDirectoryStream(..)
。
如果您想要子目录中的所有文件,Files.walkFileTree(..)
可能更容易使用。您只需要实现一个FileVisitor
,它使用与{{1}相同的逻辑存储您在此过程中收集的List
或Set
个Path
个对象上面。