Created
January 12, 2014 13:14
-
-
Save narqo/8384437 to your computer and use it in GitHub Desktop.
Comparison of different ways to implement `fs#scan()`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'), | |
path = require('path'); | |
/** | |
* Async version of `scan` | |
* | |
* @example | |
* var scan = require('./scan-async'); | |
* scan('<dir>', function(err, files) { | |
* // do something with `files` object | |
* }); | |
* | |
* @param {String} dir | |
* @param {Function} cb | |
*/ | |
module.exports = function scan(dir, cb) { | |
dir = path.resolve(dir); | |
var flat = [], | |
files = { | |
flat : flat | |
}; | |
walk(dir, function(err) { | |
if(err) return cb(err); | |
cb(null, files); | |
}); | |
function push(item) { | |
flat.push({ file: item.fullpath }); | |
} | |
function walk(dir, cb) { | |
_walk(dir, function(f, next) { | |
if(f.stat.isDirectory()) { | |
walk(f.fullpath, next); | |
return; | |
} | |
if(f.stat.isFile()) { | |
push(f); | |
} | |
next(); | |
}, cb); | |
} | |
}; | |
function _walk(dir, onFile, done) { | |
fs.readdir(dir, traverse); | |
function traverse(err, files) { | |
if(err) { | |
done(err); | |
return; | |
} | |
var pending = files.length; | |
if(pending === 0) { | |
done(); | |
return; | |
} | |
files.forEach(function(f) { | |
if(f[0] === '.') { | |
next(); | |
return; | |
} | |
var p = dir + '/' + f; | |
onFile({ | |
dir : dir, | |
file : f, | |
fullpath : p, | |
stat : fs.statSync(p) | |
}, next); | |
}); | |
function next(err) { | |
--pending === 0 && done(err); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'), | |
path = require('path'), | |
through = require('through'); | |
/** | |
* Stream version of `scan` | |
* | |
* @example | |
* var scan = require('./scan-stream'); | |
* var concat = require('concat-stream'); | |
* scan('<dir>').pipe(concat(function(files) { | |
* // do something with `files` object | |
* }); | |
* | |
* @param {String} dir | |
* @returns {Stream} ReadableWritable (through) stream | |
*/ | |
module.exports = function scan(dir) { | |
dir = path.resolve(dir); | |
var flat = [], | |
files = { | |
flat : flat | |
}, | |
tr = through(), | |
pending = 0; | |
walk(dir); | |
return tr.pipe(through(write, end)); | |
function push(item) { | |
tr.queue({ file: item.fullpath }); | |
} | |
function write(item) { | |
flat.push(item); | |
} | |
function end() { | |
this.queue(files); | |
this.queue(null); | |
} | |
function walk(dir) { | |
++pending; | |
var t = through(function write(f) { | |
if(f.stat.isDirectory()) { | |
walk(f.fullpath).pipe(t); | |
return; | |
} | |
if(f.stat.isFile()) { | |
push(f); | |
} | |
}, function() { | |
this.queue(null); | |
if(--pending === 0) tr.queue(null); | |
}); | |
return _walk(dir).pipe(t); | |
} | |
}; | |
function _walk(dir) { | |
var tr = through(); | |
fs.readdir(dir, function(err, files) { | |
if(err) { | |
tr.emit('error', err); | |
return; | |
} | |
files.forEach(function(f) { | |
if(f[0] === '.') return; | |
var p = dir + '/' + f; | |
tr.queue({ | |
dir : dir, | |
file : f, | |
fullpath : p, | |
stat : fs.statSync(p) | |
}); | |
}); | |
tr.queue(null); | |
}); | |
return tr; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'), | |
path = require('path'); | |
/** | |
* Sync version of `scan` | |
* | |
* @example | |
* var scan = require('./scan-sync'); | |
* var files = scan('<dir>'); | |
* | |
* @param {String} dir | |
* @returns {Object} | |
*/ | |
module.exports = function scan(dir) { | |
dir = path.resolve(dir); | |
var flat = [], | |
files = { | |
flat : flat | |
}; | |
walk(dir); | |
return files; | |
function push(item) { | |
flat.push({ file: item.fullpath }); | |
} | |
function walk(dir) { | |
var files = _walk(dir); | |
files.forEach(function(f) { | |
if(f.stat.isDirectory()) { | |
walk(f.fullpath); | |
return; | |
} | |
if(f.stat.isFile()) { | |
push(f); | |
} | |
}); | |
} | |
}; | |
function _walk(dir) { | |
var files = fs.readdirSync(dir); | |
if(files.length === 0) { | |
return []; | |
} | |
return files.reduce(function(files, f) { | |
if(f[0] === '.') return files; | |
var p = dir + '/' + f; | |
files.push({ | |
dir : dir, | |
file : f, | |
fullpath : p, | |
stat : fs.statSync(p) | |
}); | |
return files; | |
}, []); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some silly benchmarks:
Making 1000 scans: