Delete files older than x days

79,449

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
            }
        }
    });
}
Share:
79,449

Related videos on Youtube

user2065929
Author by

user2065929

Updated on July 09, 2022

Comments

  • user2065929
    user2065929 11 months

    How 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 : 1361635382096
    

    How 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
    NathanChristie about 8 years
    Is there any way you can combine the AgeFileFilter with another filter, such as the NameFileFilter?
  • maxb3k
    maxb3k almost 8 years
    @NathanChristie see AndFileFilter and OrFileFilter
  • thijsraets over 7 years
    Parameters: iterateFiles(File directory, IOFileFilter fileFilter, IOFileFilter dirFilter), dirfilter is optional (can be null)
  • SuperBiasedMan
    SuperBiasedMan almost 7 years
    It'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 years
    It'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
    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
    Nate over 3 years
    To be clear, AgeFileFilter is from Apache Commons IO, not from the Java 8 Time API.
  • Matt Harrison
    Matt Harrison over 2 years
    I 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
    CeePlusPlus almost 2 years
    Would suggest using System.currentTimeMillis(), also I think it should be > .
  • NickL over 1 year
    Example does not compile, cannot iterate over Iterator Probably want to use listFiles?

Related