Delete files older than x days
Solution 1
Commons IO has built-in support for filtering files by age with its AgeFileFilter. Your DeleteFiles could just look like this:
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AgeFileFilter;
import static org.apache.commons.io.filefilter.TrueFileFilter.TRUE;
// a Date defined somewhere for the cutoff date
Date thresholdDate = <the oldest age you want to keep>;
public void DeleteFiles(File file) {
Iterator<File> filesToDelete =
FileUtils.iterateFiles(file, new AgeFileFilter(thresholdDate), TRUE);
for (File aFile : filesToDelete) {
aFile.delete();
}
}
Update: To use the value as given in your edit, define the thresholdDate as:
Date tresholdDate = new Date(1361635382096L);
Solution 2
Using Apache utils is probably the easiest. Here is the simplest solution I could come up with.
public void deleteOldFiles() {
Date oldestAllowedFileDate = DateUtils.addDays(new Date(), -3); //minus days from current date
File targetDir = new File("C:\\TEMP\\archive\\");
Iterator<File> filesToDelete = FileUtils.iterateFiles(targetDir, new AgeFileFilter(oldestAllowedFileDate), null);
//if deleting subdirs, replace null above with TrueFileFilter.INSTANCE
while (filesToDelete.hasNext()) {
FileUtils.deleteQuietly(filesToDelete.next());
} //I don't want an exception if a file is not deleted. Otherwise use filesToDelete.next().delete() in a try/catch
}
Solution 3
Example using Java 8's Time API
LocalDate today = LocalDate.now();
LocalDate eailer = today.minusDays(30);
Date threshold = Date.from(eailer.atStartOfDay(ZoneId.systemDefault()).toInstant());
AgeFileFilter filter = new AgeFileFilter(threshold);
File path = new File("...");
File[] oldFolders = FileFilterUtils.filter(filter, path);
for (File folder : oldFolders) {
System.out.println(folder);
}
Solution 4
Here's Java 8 version using Time API. It's been tested and used in our project:
public static int deleteFiles(final Path destination,
final Integer daysToKeep) throws IOException {
final Instant retentionFilePeriod = ZonedDateTime.now()
.minusDays(daysToKeep).toInstant();
final AtomicInteger countDeletedFiles = new AtomicInteger();
Files.find(destination, 1,
(path, basicFileAttrs) -> basicFileAttrs.lastModifiedTime()
.toInstant().isBefore(retentionFilePeriod))
.forEach(fileToDelete -> {
try {
if (!Files.isDirectory(fileToDelete)) {
Files.delete(fileToDelete);
countDeletedFiles.incrementAndGet();
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
return countDeletedFiles.get();
}
Solution 5
Using lambdas (Java 8+)
Non recursive option to delete all files in current folder that are older than N days (ignores sub folders):
public static void deleteFilesOlderThanNDays(int days, String dirPath) throws IOException {
long cutOff = System.currentTimeMillis() - (days * 24 * 60 * 60 * 1000);
Files.list(Paths.get(dirPath))
.filter(path -> {
try {
return Files.isRegularFile(path) && Files.getLastModifiedTime(path).to(TimeUnit.MILLISECONDS) < cutOff;
} catch (IOException ex) {
// log here and move on
return false;
}
})
.forEach(path -> {
try {
Files.delete(path);
} catch (IOException ex) {
// log here and move on
}
});
}
Recursive option, that traverses sub-folders and deletes all files that are older than N days:
public static void recursiveDeleteFilesOlderThanNDays(int days, String dirPath) throws IOException {
long cutOff = System.currentTimeMillis() - (days * 24 * 60 * 60 * 1000);
Files.list(Paths.get(dirPath))
.forEach(path -> {
if (Files.isDirectory(path)) {
try {
recursiveDeleteFilesOlderThanNDays(days, path.toString());
} catch (IOException e) {
// log here and move on
}
} else {
try {
if (Files.getLastModifiedTime(path).to(TimeUnit.MILLISECONDS) < cutOff) {
Files.delete(path);
}
} catch (IOException ex) {
// log here and move on
}
}
});
}
Related videos on Youtube
user2065929
Updated on July 09, 2022Comments
-
user2065929 11 monthsHow can I find out when a file was created using java, as I wish to delete files older than a certain time period, currently I am deleting all files in a directory, but this is not ideal:
public void DeleteFiles() { File file = new File("D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/"); System.out.println("Called deleteFiles"); DeleteFiles(file); File file2 = new File("D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/"); DeleteFilesNonPdf(file2); } public void DeleteFiles(File file) { System.out.println("Now will search folders and delete files,"); if (file.isDirectory()) { for (File f : file.listFiles()) { DeleteFiles(f); } } else { file.delete(); } }Above is my current code, I am trying now to add an if statement in that will only delete files older than say a week.
EDIT:
@ViewScoped @ManagedBean public class Delete { public void DeleteFiles() { File file = new File("D:/Documents/NetBeansProjects/printing~subversion/fileupload/web/resources/pdf/"); System.out.println("Called deleteFiles"); DeleteFiles(file); File file2 = new File("D:/Documents/NetBeansProjects/printing~subversion/fileupload/Uploaded/"); DeleteFilesNonPdf(file2); } public void DeleteFiles(File file) { System.out.println("Now will search folders and delete files,"); if (file.isDirectory()) { System.out.println("Date Modified : " + file.lastModified()); for (File f : file.listFiles()) { DeleteFiles(f); } } else { file.delete(); } }Adding a loop now.
EDIT
I have noticed while testing the code above I get the last modified in :
INFO: Date Modified : 1361635382096How should I code the if loop to say if it is older than 7 days delete it when it is in the above format?
-
NathanChristie about 8 yearsIs there any way you can combine the AgeFileFilter with another filter, such as the NameFileFilter? -
maxb3k almost 8 years@NathanChristie see AndFileFilter and OrFileFilter -
thijsraets over 7 yearsParameters: iterateFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter), dirfilter is optional (can be null)
-
SuperBiasedMan almost 7 yearsIt's more helpful to explain the parts that the OP doesn't understand, rather than providing them with a bulk of code that does approximately what they wanted. Take a look at the accepted answer here, it has much less code than yours, but more explanation and it solved the question succinctly. -
Glenn Lawrence over 6 yearsIt's also worth noting that you can use milliseconds to create an AgeFileFilter like this
new AgeFileFilter(System.currentTimeMillis() - AGE_LIMIT_MILLIS)where AGE_LIMIT_MILLIS could be say 24*60*60*1000L for 24 hours. -
diwa about 6 years@MattC Does this have any impact like out of memory exception if i use it for the directory having 2 or 3 million records?
-
MattC about 6 years@Diwa Yes, I am guessing you could run into memory issues if you had millions of files. FileUtils creates a java.util.LinkedList, and then returns the iterator of that list. -
Nate over 3 yearsTo be clear, AgeFileFilter is from Apache Commons IO, not from the Java 8 Time API. -
Matt Harrison over 2 yearsI was adapting this for what I needed, and had a warning from SonarQube noting that the Files.find stream should be closed, or ideally put into a try with resources block. -
CeePlusPlus almost 2 yearsWould suggest usingSystem.currentTimeMillis(), also I think it should be>. -
NickL over 1 yearExample does not compile, cannot iterate over
IteratorProbably want to use listFiles?