If I get this right, you have 2 situations:
- Create a custom
filter
to select files older than 60 days - Traverse through subdirectories (the entire
FileTree
) and gather your information
The custom filter is easier to implement with conditions of 60 days implemented using Calendar
class:
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);
}
};
The normal execution would only look for the files in the root directory. To look for subdirectory, your guess of using walkFileTree()
is right.
However, this requires an implementation of the FileVisitor
interface, a simple implementation of which luckily is bundled with 7 - SimpleFileVisitor
.
To traverse through the subdirectories, you can choose to override a directory specific method - I have used preVisitDirectory
of SimpleFileVisitor
here:
Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path file,
BasicFileAttributes attrs) {
Since preVisitDirectory
will be custom made to return FileVisitResult.CONTINUE;
in case you don't have any additional restrictions, we would leverage preVisitDirectory
method to iterate through our directory 1 at a time while applying the filter.
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;
}
});
This would give you the files from the entire directory and subdirectory structures for the required filter criteria, complete main method below:
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;
}
});
}