2

Are there any methods for obtaining the oldest file in a directory using java? I have a directory i write log files to and would like to delete log files after ive recorded over 500 log files (but only want to delete the oldest ones).

The only way i could conceive myself is:

  • Get the list of files using the File.listFiles() method
  • Loop through each File
  • Store the last modified date using File.lastModified() and compare with File from loop iteration, keep the oldest lastModified()

The inconvenient aspect of this logic is that i would have to loop the log directory every time i want to get the oldest files and that does not seem the most efficient.

i expected the java.io.File library would have a method to get the oldest file in a directory but it doesnt seem to exist, or i havent found it. If there is a method for obtaining the oldest file in a directory or a more convenient approach in programming the solution, i would love to know.

Thanks

Benji Weiss
  • 406
  • 2
  • 6
  • 19
  • 6
    This method that you wish to find, would have to do exactly the same, loop through all the files. – Yoda Mar 25 '19 at 21:47
  • The Java logger can do rotating log files, relieving you of the need to keep track of this. See https://stackoverflow.com/questions/16522339/rolling-log-files-removing-old-log-files/16524062#16524062. (Actually every logging framework can, but I prefer not to rely on third party libraries if it’s not necessary.) – VGR Mar 26 '19 at 02:27

2 Answers2

3

Based off of @Yoda comment, i figured i would answer my own question.

public static void main(String[] args) throws IOException {
    File directory = new File("/logFiles");
    purgeLogFiles(directory);
}

public void purgeLogFiles(File logDir){
    File[] logFiles = logDir.listFiles();
    long oldestDate = Long.MAX_VALUE;
    File oldestFile = null;
    if( logFiles != null && logFiles.length >499){
        //delete oldest files after theres more than 500 log files
        for(File f: logFiles){
            if(f.lastModified() < oldestDate){
                oldestDate = f.lastModified();
                oldestFile = f;
            }               
        }

        if(oldestFile != null){
            oldestFile.delete();
        }
    }
}
Benji Weiss
  • 406
  • 2
  • 6
  • 19
  • I'm not sure you can pass a String into that method in your proposed solution. Probably meant to create a file object? – simgineer Jun 28 '19 at 23:34
1

Unfortunately, you're gonna have to just walk the filesystem. Something like:

public static void main(String[] args) throws IOException {
    String parentFolder = "/var/log";
    int numberOfOldestFilesToFind = 5;

    List<Path> oldestFiles = findOldestFiles(parentFolder, numberOfOldestFilesToFind);

    System.out.println(oldestFiles);
}

private static List<Path> findOldestFiles(String parentFolder, int numberOfOldestFilesToFind) throws IOException {
    Comparator<? super Path> lastModifiedComparator = 
            (p1, p2) -> Long.compare(p1.toFile().lastModified(),
                                     p2.toFile().lastModified());

    List<Path> oldestFiles = Collections.emptyList();

    try (Stream<Path> paths = Files.walk(Paths.get(parentFolder))) {
        oldestFiles = paths.filter(Files::isRegularFile)
                           .sorted(lastModifiedComparator)
                           .limit(numberOfOldestFilesToFind)
                           .collect(Collectors.toList());
    }

    return oldestFiles;
}
Not a JD
  • 1,864
  • 6
  • 14