2010-11-21 05:02:53 +00:00
|
|
|
node-walk
|
|
|
|
====
|
|
|
|
|
2011-02-04 07:35:56 +00:00
|
|
|
nodejs walk implementation.
|
2011-02-03 21:44:01 +00:00
|
|
|
|
|
|
|
This is somewhat of a port python's `os.walk`, but using Node.JS conventions.
|
2010-12-12 08:58:43 +00:00
|
|
|
|
|
|
|
* EventEmitter
|
|
|
|
* Asynchronous
|
|
|
|
* Chronological (optionally)
|
|
|
|
* Built-in flow-control
|
2011-05-03 03:11:03 +00:00
|
|
|
* includes Synchronous version (same API as Asynchronous)
|
2010-12-12 08:58:43 +00:00
|
|
|
|
|
|
|
As few file descriptors are opened at a time as possible.
|
|
|
|
This is particularly well suited for single hard disks which are not flash or solid state.
|
|
|
|
|
2010-11-21 05:02:53 +00:00
|
|
|
Installation
|
|
|
|
----
|
|
|
|
|
|
|
|
npm install walk
|
|
|
|
|
|
|
|
Usage
|
|
|
|
====
|
|
|
|
|
2011-05-03 03:11:03 +00:00
|
|
|
Both Asynchronous and Synchronous versions are provided.
|
|
|
|
|
|
|
|
The Synchronous version still uses callbacks, so it is safe to use with other Asynchronous functions and will still work as expected.
|
|
|
|
|
2011-02-12 21:42:06 +00:00
|
|
|
var walk = require('walk'),
|
|
|
|
fs = require('fs'),
|
2010-12-12 08:58:43 +00:00
|
|
|
options,
|
|
|
|
walker;
|
|
|
|
|
|
|
|
options = {
|
2010-12-02 10:09:01 +00:00
|
|
|
followLinks: false,
|
2013-04-20 20:29:37 +00:00
|
|
|
// filters: ["Temp", "_Temp"] // directories with these
|
|
|
|
// keys will be skipped
|
2010-12-12 08:58:43 +00:00
|
|
|
};
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2011-05-03 03:11:03 +00:00
|
|
|
walker = walk.walk("/tmp", options);
|
|
|
|
|
|
|
|
// OR
|
|
|
|
// walker = walk.walkSync("/tmp", options);
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2011-02-04 07:14:19 +00:00
|
|
|
walker.on("names", function (root, nodeNamesArray) {
|
2013-03-05 21:58:24 +00:00
|
|
|
nodeNamesArray.sort(function (a, b) {
|
2011-02-04 07:14:19 +00:00
|
|
|
if (a > b) return 1;
|
|
|
|
if (a < b) return -1;
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
walker.on("directories", function (root, dirStatsArray, next) {
|
|
|
|
// dirStatsArray is an array of `stat` objects with the additional attributes
|
|
|
|
// * type
|
|
|
|
// * error
|
|
|
|
// * name
|
|
|
|
|
|
|
|
next();
|
|
|
|
});
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
walker.on("file", function (root, fileStats, next) {
|
2011-02-12 21:42:06 +00:00
|
|
|
fs.readFile(fileStats.name, function () {
|
2010-12-12 08:58:43 +00:00
|
|
|
// doStuff
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
});
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
walker.on("errors", function (root, nodeStatsArray, next) {
|
|
|
|
next();
|
|
|
|
});
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 09:13:40 +00:00
|
|
|
walker.on("end", function () {
|
|
|
|
console.log("all done");
|
|
|
|
});
|
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
API
|
|
|
|
====
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
Emitted Values
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2011-02-04 07:14:19 +00:00
|
|
|
* `on('XYZ', function(root, stats, next) {})`
|
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
* `root` - the containing the files to be inspected
|
|
|
|
* *stats[Array]* - a single `stats` object or an array with some added attributes
|
|
|
|
* type - 'file', 'directory', etc
|
|
|
|
* error
|
|
|
|
* name - the name of the file, dir, etc
|
|
|
|
* next - no more files will be read until this is called
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
Single Events - fired immediately
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 09:13:40 +00:00
|
|
|
* `end` - No files, dirs, etc left to inspect
|
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
* `directoryError` - Error when `fstat` succeeded, but reading path failed (Probably due to permissions).
|
2011-02-04 07:14:19 +00:00
|
|
|
* `nodeError` - Error `fstat` did not succeeded.
|
2010-12-12 08:58:43 +00:00
|
|
|
* `node` - a `stats` object for a node of any type
|
|
|
|
* `file` - includes links when `followLinks` is `true`
|
2011-02-04 07:14:19 +00:00
|
|
|
* Note: This feature is broken in the current version, but works in the previous `walk-recursive` version
|
2010-12-12 08:58:43 +00:00
|
|
|
* `directory`
|
2011-02-04 07:14:19 +00:00
|
|
|
* `symbolicLink` - always empty when `followLinks` is `true`
|
2010-12-12 08:58:43 +00:00
|
|
|
* `blockDevice`
|
|
|
|
* `characterDevice`
|
|
|
|
* `FIFO`
|
|
|
|
* `socket`
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 09:39:25 +00:00
|
|
|
Events with Array Arguments - fired after all files in the dir have been `stat`ed
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2011-02-04 07:14:19 +00:00
|
|
|
* `names` - before any `stat` takes place. Useful for sorting and filtering.
|
|
|
|
* Note: the array is an array of `string`s, not `stat` objects
|
|
|
|
* Note: the `next` argument is a `noop`
|
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
* `errors` - errors encountered by `fs.stat` when reading ndes in a directory
|
|
|
|
* `nodes` - an array of `stats` of any type
|
|
|
|
* `files`
|
|
|
|
* `directories` - modification of this array - sorting, removing, etc - affects traversal
|
2011-02-04 07:14:19 +00:00
|
|
|
* `symbolicLinks`
|
2010-12-12 08:58:43 +00:00
|
|
|
* `blockDevices`
|
|
|
|
* `characterDevices`
|
|
|
|
* `FIFOs`
|
|
|
|
* `sockets`
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2011-02-04 07:14:19 +00:00
|
|
|
**Warning** beware of infinite loops when `followLinks` is true (using `walk-recurse` varient).
|
2010-12-12 08:58:43 +00:00
|
|
|
|
|
|
|
Comparisons
|
2010-11-21 05:02:53 +00:00
|
|
|
====
|
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
Tested on my `/System` containing 59,490 (+ self) directories (and lots of files).
|
|
|
|
The size of the text output was 6mb.
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
`find`:
|
|
|
|
time bash -c "find /System -type d | wc"
|
|
|
|
59491 97935 6262916
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
real 2m27.114s
|
|
|
|
user 0m1.193s
|
|
|
|
sys 0m14.859s
|
2010-11-21 05:02:53 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
`find.js`:
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2010-12-12 08:58:43 +00:00
|
|
|
Note that `find.js` omits the start directory
|
|
|
|
|
|
|
|
time bash -c "node examples/find.js /System -type d | wc"
|
|
|
|
59490 97934 6262908
|
|
|
|
|
|
|
|
# Test 1
|
|
|
|
real 2m52.273s
|
|
|
|
user 0m20.374s
|
|
|
|
sys 0m27.800s
|
|
|
|
|
|
|
|
# Test 2
|
|
|
|
real 2m23.725s
|
|
|
|
user 0m18.019s
|
|
|
|
sys 0m23.202s
|
|
|
|
|
|
|
|
# Test 3
|
|
|
|
real 2m50.077s
|
|
|
|
user 0m17.661s
|
|
|
|
sys 0m24.008s
|
2010-12-02 10:09:01 +00:00
|
|
|
|
2011-05-03 03:11:03 +00:00
|
|
|
In conclusion node.js asynchronous walk is much slower than regular "find".
|
2012-05-08 15:57:33 +00:00
|
|
|
|
|
|
|
LICENSE
|
|
|
|
===
|
|
|
|
|
|
|
|
`node-walk` is available under the following licenses:
|
|
|
|
|
|
|
|
* MIT
|
|
|
|
* Apache 2
|
|
|
|
|
|
|
|
Copyright 2011 - Present AJ ONeal
|