Close

Java - How to delete old files under a folder if number of files are over a specified limit?

[Last Updated: Aug 30, 2020]

Java IO & NIO 

Following example shows how keep number of files under a folder constant by deleting older files. This can be useful for the scenarios like persisting same type of events under a folder but we don't want the target folder to increase in size infinitely e.g. UI undo/redo actions, creating logs files by dates (similar to rolling behavior) etc.

Example

package com.logicbig.example;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class DeleteOldFilesExample {

  public static void main(String[] args) throws IOException, InterruptedException {
      //create test files
      Path dir = Files.createTempDirectory("test-dir-" + LocalDate.now().toString());
      System.out.println("folder: "+dir);
      dir.toFile().deleteOnExit();
      for (int i = 0; i < 10; i++) {
          Path file = Files.createFile(dir.resolve(Integer.toString(i + 1)+".txt"));
          file.toFile().deleteOnExit();
          Thread.sleep(1000);
      }

      System.out.println("-- before deleting old files if more than 5 --");
      getSortedFilesByDateCreated(dir, null, true)
              .forEach(f -> System.out.println(f.toFile().getName()+ " - "
                      +getFileCreationDateTime(f.toFile())));

      System.out.println("-- deleting old files --");
      deleteOldFiles(dir, ".txt", 5);

      System.out.println("-- after deleting old files if more than 5 --");
      getSortedFilesByDateCreated(dir, null, true)
              .forEach(f -> System.out.println(f.toFile().getName()+ " - "
                      +getFileCreationDateTime(f.toFile())));
  }


  public static void deleteOldFiles(Path parentFolder, String extensionCouldBeNull, int limit) {
      List<Path> files = getSortedFilesByDateCreated(parentFolder, extensionCouldBeNull, false);
      if(files.size()<=limit){
          return;
      }
      //delete recent files and keeping old files in the list
      files.subList(0, limit).clear();

      //deleting old files
      files.forEach(p -> {
          try {
              Files.delete(p);
          } catch (IOException e) {
              e.printStackTrace();
          }
      });
  }

  public static List<Path> getSortedFilesByDateCreated(Path parentFolder, String targetExtensionCouldBeNull,
                                                       boolean ascendingOrder) {
      try {
          Comparator<Path> pathComparator = Comparator.comparingLong(p -> getFileCreationEpoch((p).toFile()));
          return Files.list(parentFolder)
                      .filter(Files::isRegularFile)
                      .filter(p -> targetExtensionCouldBeNull == null || p.getFileName().toString()
                                                                          .endsWith(targetExtensionCouldBeNull))
                      .sorted(ascendingOrder? pathComparator :
                              pathComparator.reversed())
                      .collect(Collectors.toList());
      } catch (IOException e) {
          throw new RuntimeException(e);
      }
  }

  public static long getFileCreationEpoch(File file) {
      try {
          BasicFileAttributes attr = Files.readAttributes(file.toPath(),
                  BasicFileAttributes.class);
          return attr.creationTime()
                     .toInstant().toEpochMilli();
      } catch (IOException e) {
         throw new RuntimeException(e);
      }
  }

  public static LocalDateTime getFileCreationDateTime(File file) {
      try {
          BasicFileAttributes attr = Files.readAttributes(file.toPath(),
                  BasicFileAttributes.class);
          return attr.creationTime()
                     .toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
      } catch (IOException e) {
          throw new RuntimeException(e);
      }
  }
}
folder: C:\Users\joe\AppData\Local\Temp\test-dir-2020-08-2914400418823882994423
-- before deleting more than 5 files --
1.txt - 2020-08-29T23:16:34.000018800
2.txt - 2020-08-29T23:16:35.004101100
3.txt - 2020-08-29T23:16:36.007188700
4.txt - 2020-08-29T23:16:37.010725
5.txt - 2020-08-29T23:16:38.013813900
6.txt - 2020-08-29T23:16:39.015520400
7.txt - 2020-08-29T23:16:40.018661900
8.txt - 2020-08-29T23:16:41.021483900
9.txt - 2020-08-29T23:16:42.023571200
10.txt - 2020-08-29T23:16:43.027415300
-- deleting old files --
-- after deleting more than 5 files --
6.txt - 2020-08-29T23:16:39.015520400
7.txt - 2020-08-29T23:16:40.018661900
8.txt - 2020-08-29T23:16:41.021483900
9.txt - 2020-08-29T23:16:42.023571200
10.txt - 2020-08-29T23:16:43.027415300

See Also