Newtang
Newtang

Reputation: 6544

Using Node.JS, how do you get a list of files in chronological order?

For a given directory, how can I get a list of files in chronological order (by date-modified) in Node.JS? I didn't see anything in the File System docs.

Upvotes: 51

Views: 45867

Answers (5)

Krzysztof Rosiński
Krzysztof Rosiński

Reputation: 880

2021, async/await using fs.promises

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

async function readdirChronoSorted(dirpath, order) {
  order = order || 1;
  const files = await fs.readdir(dirpath);
  const stats = await Promise.all(
    files.map((filename) =>
      fs.stat(path.join(dirpath, filename))
        .then((stat) => ({ filename, mtime: stat.mtime }))
    )
  );
  return stats.sort((a, b) =>
    order * (b.mtime.getTime() - a.mtime.getTime())
  ).map((stat) => stat.filename);
}

(async () => {
  try {
    const dirpath = __dirname;
    console.log(await readdirChronoSorted(dirpath));
    console.log(await readdirChronoSorted(dirpath, -1));
  } catch (err) {
    console.log(err);
  }
})();

Upvotes: 15

milahu
milahu

Reputation: 3559

a compact version of the cliffs of insanity solution

function readdirSortTime(dir, timeKey = 'mtime') {
  return (
    fs.readdirSync(dir)
    .map(name => ({
      name,
      time: fs.statSync(`${dir}/${name}`)[timeKey].getTime()
    }))
    .sort((a, b) => (a.time - b.time)) // ascending
    .map(f => f.name)
  );
}

Upvotes: 3

Ismael Martinez
Ismael Martinez

Reputation: 31

I ended up using underscore as gives the opportunity to account for what stat to use for the sorting.

1st get the files in the directory using files = fs.readFileSync(directory); (you might want to try catch err in case directory does not exist or read permissions)

Then pass them to a function like the following one. That will return you the ordered list.

function orderByCTime(directory, files) {
    var filesWithStats = [];
    _.each(files, function getFileStats(file) {
        var fileStats = fs.statSync(directory + file);

        filesWithStats.push({
            filename: file,
            ctime: fileStats.ctime
        });
        file = null;
    });
    return _.sortBy(filesWithStats, 'ctime').reverse();
}

Underscore sort by asc by default. I reverse it as I need it descending order.

You could decide to sort by another stat (check node fs documentation here). I choose to use ctime as it should account for "touching" the file also.

Hope helps,

Upvotes: 0

cliffs of insanity
cliffs of insanity

Reputation: 3694

Give this a shot.

var dir = './'; // your directory

var files = fs.readdirSync(dir);
files.sort(function(a, b) {
               return fs.statSync(dir + a).mtime.getTime() - 
                      fs.statSync(dir + b).mtime.getTime();
           });

I used the "sync" version of the methods. You should make them asynchronous as needed. (Probably just the readdir part.)


You can probably improve performance a bit if you cache the stat info.

var files = fs.readdirSync(dir)
              .map(function(v) { 
                  return { name:v,
                           time:fs.statSync(dir + v).mtime.getTime()
                         }; 
               })
               .sort(function(a, b) { return a.time - b.time; })
               .map(function(v) { return v.name; });

Upvotes: 106

Chase
Chase

Reputation: 29549

Have you tried fs.readdir()?

http://nodejs.org/docs/v0.3.1/api/fs.html#fs.readdir

Upvotes: -3

Related Questions