Delete files older than x days

扶醉桌前 提交于 2019-11-28 07:12:48

You can use File.lastModified() to get the last modified time of a file/directory.

Can be used like this:

long diff = new Date().getTime() - file.lastModified();

if (diff > x * 24 * 60 * 60 * 1000) {
    file.delete();
}

Which deletes files older than x (an int) days.

Ryan Stewart

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);

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);
}
MattC

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
}

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
            }
        }
    });
}

For a JDK 8 solution using both NIO file streams and JSR-310

long cut = LocalDateTime.now().minusWeeks(1).toEpochSecond(ZoneOffset.UTC);
Path path = Paths.get("/path/to/delete");
Files.list(path)
        .filter(n -> {
            try {
                return Files.getLastModifiedTime(n)
                        .to(TimeUnit.SECONDS) < cut;
            } catch (IOException ex) {
                //handle exception
                return false;
            }
        })
        .forEach(n -> {
            try {
                Files.delete(n);
            } catch (IOException ex) {
                //handle exception
            }
        });

The sucky thing here is the need for handling exceptions within each lambda. It would have been great for the API to have UncheckedIOException overloads for each IO method. With helpers to do this one could write:

public static void main(String[] args) throws IOException {
    long cut = LocalDateTime.now().minusWeeks(1).toEpochSecond(ZoneOffset.UTC);
    Path path = Paths.get("/path/to/delete");
    Files.list(path)
            .filter(n -> Files2.getLastModifiedTimeUnchecked(n)
                    .to(TimeUnit.SECONDS) < cut)
            .forEach(n -> {
                System.out.println(n);
                Files2.delete(n, (t, u)
                              -> System.err.format("Couldn't delete %s%n",
                                                   t, u.getMessage())
                );
            });
}


private static final class Files2 {

    public static FileTime getLastModifiedTimeUnchecked(Path path,
            LinkOption... options)
            throws UncheckedIOException {
        try {
            return Files.getLastModifiedTime(path, options);
        } catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    public static void delete(Path path, BiConsumer<Path, Exception> e) {
        try {
            Files.delete(path);
        } catch (IOException ex) {
            e.accept(path, ex);
        }
    }

}

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();
}

Another approach with Apache commons-io and joda:

private void deleteOldFiles(String dir, int daysToRemainFiles) {
    Collection<File> filesToDelete = FileUtils.listFiles(new File(dir),
            new AgeFileFilter(DateTime.now().withTimeAtStartOfDay().minusDays(daysToRemainFiles).toDate()),
            TrueFileFilter.TRUE);    // include sub dirs
    for (File file : filesToDelete) {
        boolean success = FileUtils.deleteQuietly(file);
        if (!success) {
            // log...
        }
    }
}

You can get the creation date of the file using NIO, following is the way:

BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
System.out.println("creationTime: " + attrs.creationTime());

More about it can be found here : http://docs.oracle.com/javase/tutorial/essential/io/fileAttr.html

Using Java NIO Files with lambdas & Commons IO

final long time = new Date().getTime();
// Only show files & directories older than 2 days
final long maxdiff = TimeUnit.DAYS.toMillis(2);

List all found files and directories:

Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff)
.forEach(System.out::println);

Or delete found files with FileUtils:

Files.newDirectoryStream(Paths.get("."), p -> (time - p.toFile().lastModified()) < maxdiff)
.forEach(p -> FileUtils.deleteQuietly(p.toFile()));
Pankaj Dagar

Here is the code to delete files which are not modified since six months & also create the log file.

package deleteFiles;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class Delete {
    public static void deleteFiles()
    {
        int numOfMonths = -6;
        String path="G:\\Files";
        File file = new File(path);
        FileHandler fh;
        Calendar sixMonthAgo = Calendar.getInstance();
        Calendar currentDate = Calendar.getInstance();
        Logger logger = Logger.getLogger("MyLog");
        sixMonthAgo.add(Calendar.MONTH, numOfMonths);
        File[] files = file.listFiles();
        ArrayList<String> arrlist = new ArrayList<String>();

        try {
            fh = new FileHandler("G:\\Files\\logFile\\MyLogForDeletedFile.log");
            logger.addHandler(fh);
            SimpleFormatter formatter = new SimpleFormatter();
            fh.setFormatter(formatter);

            for (File f:files)
            {
                if (f.isFile() && f.exists())
                {
                    Date lastModDate = new Date(f.lastModified());
                    if(lastModDate.before(sixMonthAgo.getTime()))
                    {
                        arrlist.add(f.getName());
                        f.delete();
                    }
                }
            }
            for(int i=0;i<arrlist.size();i++)
                logger.info("deleted files are ===>"+arrlist.get(i));
        }
        catch ( Exception e ){
            e.printStackTrace();
            logger.info("error is-->"+e);
        }
    }
    public static void main(String[] args)
    {
        deleteFiles();
    }
}

Using Apache commons-io and joda:

        if ( FileUtils.isFileOlder(f, DateTime.now().minusDays(30).toDate()) ) {
            f.delete();
        }

Need to point out a bug on the first solution listed, x * 24 * 60 * 60 * 1000 will max out int value if x is big. So need to cast it to long value

long diff = new Date().getTime() - file.lastModified();

if (diff > (long) x * 24 * 60 * 60 * 1000) {
    file.delete();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!