How get to the latest 50 files in a folder based on the file creation time

74 views Asked by At

I have a folder containing thousands of files. I plan to read the latest 50 files based on the date created, Java by default reading files created oldest, comparing each file taking lot of time, is there a better way to do this?

I have a Folder \usr\documents\archive have 1000 files in it want to read 50 documents in the folder based on the file creation.

2

There are 2 answers

0
Sagar Gandhi On

You can use following to get creation or last modification time

  BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
    FileTime fileTime = attr.creationTime();

OR

 FileTime creationTime = (FileTime) Files.getAttribute(path, "creationTime");

Now since you can take creation time (or last modification time), you can sort files by creation time.

Caution: Iterating each file/directory will take time but it depends on your use case. I would do it if task is running in background but not for operation where user is waiting. I would use cache to periodically process and store result for user facing operations.

0
DevilsHnd - 退した On

Below is a method that reads all files within a specified directory (folder) path and sorts the files based on creation (or modification) timestamps in either Ascending or Descending Order. A String[] Array is returned with either just the file names or path and filenames depending what is supplied within the methods optional (varArg) parameters.

/**
 * Returns a String[] Array of all the files within the supplied directory
 * (folder) in either Ascending or Descending order. By default the full
 * absolute path and the file name are returned, not just the file name.
 * <p>
 * If you want the files list to be sorted in Descending Order the supply
 * <b>1</b> within the optional <b>sortOrder</b> parameter.
 * <p>
 * If you want just the file names within the String[] Array then supply
 * <b>1</b>
 * within the optional <b>fileNamesOnly</b> parameter.
 * <p>
 * <b>Example Usage:</b><pre>
 *  {@code     String folderPath = "C:\\Log Files\\SpecificAppLogsFolder";
 *       String[] logFiles = getFolderFilesInOrder(folderPath);
 *       for (String s : logFiles) {
 *           System.out.println(s);
 *       }
 *   }</pre>
 *
 * @param folderPath (String) The full path to the file system directory
 *                   (folder) in which you want to get the list of files
 *                   from.<br>
 *
 * @param options    (Optional - int):<pre>
 *
 *      sortOrder       - Default is 0 (Ascending Order) which means the files
 *                        list will ne returned in ascending sort order (from 
 *                        the oldest files to the newest files). If any
 *                        value other than 0 (ie: 1) is supplied then the files
 *                        list will be returned in descending order (from newest
 *                        files to oldest files).
 *
 *      fileNamesOnly   - Default is 0 where Path and file name are returned within
 *                        the String[] Array. If any value other than 0 (ie: 1)
 *                        is supplied then only the file names itself will be
 *                        returned within the String[] Array.
 *
 *                        If an argument is supplied to this optional parameter
 *                        then something MUST also be supplied to the optional
 *                        <b>sortOrder</b> parameter (either 0 or 1).</pre>
 *
 * @return (One Dimensional String Array) The files contained within the
 *         supplied directory path in the desired sort order based on their
 *         Creation (last modified) timestamp.
 */
public String[] getFolderFilesInOrder(String folderPath, int... options) {
    File folder = new File(folderPath);
    if (!folder.exists() && !folder.isDirectory()) {
        System.err.println("Either the supplied folder doesn't exist "
                + "or it is not a directory!");
        return null;
    }
    int sortOrder = 0;      // Default - Ascending Order | any value other than 0 for Descending Order.
    int fileNamesOnly = 0;  // Default - Path & file name | any value other than 0 for file names only.
    if (options.length >= 1) {
        sortOrder = options[0];
        if (options.length >= 2) {
            fileNamesOnly = options[1];
        }
    }

    File[] folderFilesList = folder.listFiles();
    if (sortOrder == 0) {
        Arrays.sort(folderFilesList, Comparator.comparingLong(File::lastModified));
    }
    else {
        Arrays.sort(folderFilesList, Comparator.comparingLong(File::lastModified).reversed());
    }

    List<String> filesList = new ArrayList<>();
    for (File f : folderFilesList) {
        if (f.isFile()) {
            filesList.add(fileNamesOnly == 0 ? f.getAbsolutePath() : f.getName());
        }
    }
    return filesList.toArray(new String[0]);
}

How you might use this method could be like this:

/* Get all files (file names only) within the supplied directory path 
       (no sub-directories are processed) and sort them in descending order 
       (newest to oldest) based on creation (modification) timestamp and 
       return them in a String[] Array.                         */
String[] allFiles = getFolderFilesInOrder("C:/MyLogFilesDirectory", 1, 1);
    
// The number of files desired from the directory:
int numberOfFilesDesired = 50;
    
/* Just in case (for some reason) the supplied directory path
   does not contain the desired number of files.       */
numberOfFilesDesired = Math.min(numberOfFilesDesired, allFiles.length);
    
// Retrieve the number of files we want.
String[] desiredFiles = new String[numberOfFilesDesired];
for (int i = 0; i < numberOfFilesDesired; i++) {
    desiredFiles[i] = allFiles[i];
        
    //You can omit the line below. It's just for demo purposes:
    System.out.println((i+1) + ") " + desiredFiles[i]);
}