Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the most recent file in a directory, Node.js

Tags:

node.js

I am trying to find the most recently created file in a directory using Node.js and cannot seem to find a solution. The following code seemed to be doing the trick on one machine but on another it was just pulling a random file from the directory - as I figured it might. Basically, I need to find the newest file and ONLY that file.

var fs = require('fs'); //File System
var audioFilePath = 'C:/scanner/audio/'; //Location of recorded audio files
    var audioFile = fs.readdirSync(audioFilePath)
        .slice(-1)[0]
        .replace('.wav', '.mp3');

Many thanks!

like image 317
NightMICU Avatar asked Mar 29 '13 01:03

NightMICU


5 Answers

Assuming availability of underscore (http://underscorejs.org/) and taking synchronous approach (which doesn't utilize the node.js strengths, but is easier to grasp):

var fs = require('fs'),
    path = require('path'),
    _ = require('underscore');

// Return only base file name without dir
function getMostRecentFileName(dir) {
    var files = fs.readdirSync(dir);

    // use underscore for max()
    return _.max(files, function (f) {
        var fullpath = path.join(dir, f);

        // ctime = creation time is used
        // replace with mtime for modification time
        return fs.statSync(fullpath).ctime;
    });
}
like image 153
Ilia Barahovsky Avatar answered Nov 03 '22 06:11

Ilia Barahovsky


While not the most efficient approach, this should be conceptually straight forward:

var fs = require('fs'); //File System
var audioFilePath = 'C:/scanner/audio/'; //Location of recorded audio files
fs.readdir(audioFilePath, function(err, files) {
    if (err) { throw err; }
    var audioFile = getNewestFile(files, audioFilePath).replace('.wav', '.mp3');
    //process audioFile here or pass it to a function...
    console.log(audioFile);
});

function getNewestFile(files, path) {
    var out = [];
    files.forEach(function(file) {
        var stats = fs.statSync(path + "/" +file);
        if(stats.isFile()) {
            out.push({"file":file, "mtime": stats.mtime.getTime()});
        }
    });
    out.sort(function(a,b) {
        return b.mtime - a.mtime;
    })
    return (out.length>0) ? out[0].file : "";
}

BTW, there is no obvious reason in the original post to use synchronous file listing.

like image 30
Trevedhek Avatar answered Nov 03 '22 04:11

Trevedhek


Another approach:

const glob = require('glob')

const newestFile = glob.sync('input/*xlsx')
  .map(name => ({name, ctime: fs.statSync(name).ctime}))
  .sort((a, b) => b.ctime - a.ctime)[0].name
like image 6
pguardiario Avatar answered Nov 03 '22 05:11

pguardiario


A more functional version might look like:

import { readdirSync, lstatSync } from "fs";

const orderReccentFiles = (dir: string) =>
  readdirSync(dir)
    .filter(f => lstatSync(f).isFile())
    .map(file => ({ file, mtime: lstatSync(file).mtime }))
    .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());

const getMostRecentFile = (dir: string) => {
  const files = orderReccentFiles(dir);
  return files.length ? files[0] : undefined;
};
like image 5
mikeysee Avatar answered Nov 03 '22 05:11

mikeysee


First, you need to order files (newest at the begin)

Then, get the first element of an array for the most recent file.

I have modified code from @mikeysee to avoid the path exception so that I use the full path to fix them.

The snipped codes of 2 functions are shown below.

const fs = require('fs');
const path = require('path');

const getMostRecentFile = (dir) => {
    const files = orderReccentFiles(dir);
    return files.length ? files[0] : undefined;
};

const orderReccentFiles = (dir) => {
    return fs.readdirSync(dir)
        .filter(file => fs.lstatSync(path.join(dir, file)).isFile())
        .map(file => ({ file, mtime: fs.lstatSync(path.join(dir, file)).mtime }))
        .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
};

const dirPath = '<PATH>';
getMostRecentFile(dirPath)
like image 4
Thanwa Ch. Avatar answered Nov 03 '22 05:11

Thanwa Ch.