Reputation: 6544
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
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
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
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
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
Reputation: 29549
Have you tried fs.readdir()
?
http://nodejs.org/docs/v0.3.1/api/fs.html#fs.readdir
Upvotes: -3