| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | node-walk | 
					
						
							|  |  |  | ==== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-03 23:35:56 -08:00
										 |  |  | nodejs walk implementation. | 
					
						
							| 
									
										
										
										
											2011-02-03 13:44:01 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | This is somewhat of a port python's `os.walk`, but using Node.JS conventions. | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   * EventEmitter | 
					
						
							|  |  |  |   * Asynchronous | 
					
						
							|  |  |  |   * Chronological (optionally) | 
					
						
							|  |  |  |   * Built-in flow-control | 
					
						
							| 
									
										
										
										
											2011-05-02 21:11:03 -06:00
										 |  |  |   * includes Synchronous version (same API as Asynchronous) | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07: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-20 22:02:53 -07:00
										 |  |  | Installation | 
					
						
							|  |  |  | ---- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     npm install walk | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Usage | 
					
						
							|  |  |  | ==== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 21:11:03 -06: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 13:42:06 -08:00
										 |  |  |     var walk = require('walk'), | 
					
						
							|  |  |  |       fs = require('fs'), | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |       options, | 
					
						
							|  |  |  |       walker; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     options = { | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  |         followLinks: false, | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 21:11:03 -06:00
										 |  |  |     walker = walk.walk("/tmp", options); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // OR | 
					
						
							|  |  |  |     // walker = walk.walkSync("/tmp", options); | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07:00
										 |  |  |     walker.on("names", function (root, nodeNamesArray) { | 
					
						
							|  |  |  |       nodeNames.sort(function (a, b) { | 
					
						
							|  |  |  |         if (a > b) return 1; | 
					
						
							|  |  |  |         if (a < b) return -1; | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07: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-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |     walker.on("file", function (root, fileStats, next) { | 
					
						
							| 
									
										
										
										
											2011-02-12 13:42:06 -08:00
										 |  |  |       fs.readFile(fileStats.name, function () { | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |         // doStuff | 
					
						
							|  |  |  |         next(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |     walker.on("errors", function (root, nodeStatsArray, next) { | 
					
						
							|  |  |  |       next(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 02:13:40 -07:00
										 |  |  |     walker.on("end", function () { | 
					
						
							|  |  |  |       console.log("all done"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | API | 
					
						
							|  |  |  | ==== | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | Emitted Values | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07:00
										 |  |  |   * `on('XYZ', function(root, stats, next) {})` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07: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 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | Single Events - fired immediately | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 02:13:40 -07:00
										 |  |  |   * `end` - No files, dirs, etc left to inspect | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |   * `directoryError` - Error when `fstat` succeeded, but reading path failed (Probably due to permissions). | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07:00
										 |  |  |   * `nodeError` - Error `fstat` did not succeeded. | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |   * `node` - a `stats` object for a node of any type | 
					
						
							|  |  |  |   * `file` - includes links when `followLinks` is `true` | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07:00
										 |  |  |     * Note: This feature is broken in the current version, but works in the previous `walk-recursive` version | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |   * `directory` | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07:00
										 |  |  |   * `symbolicLink` - always empty when `followLinks` is `true` | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |   * `blockDevice` | 
					
						
							|  |  |  |   * `characterDevice` | 
					
						
							|  |  |  |   * `FIFO` | 
					
						
							|  |  |  |   * `socket` | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:39:25 -08:00
										 |  |  | Events with Array Arguments - fired after all files in the dir have been `stat`ed | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07: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 01:58:43 -07: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 00:14:19 -07:00
										 |  |  |   * `symbolicLinks` | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |   * `blockDevices` | 
					
						
							|  |  |  |   * `characterDevices` | 
					
						
							|  |  |  |   * `FIFOs` | 
					
						
							|  |  |  |   * `sockets` | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 00:14:19 -07:00
										 |  |  | **Warning** beware of infinite loops when `followLinks` is true (using `walk-recurse` varient). | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | Comparisons | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | ==== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | Tested on my `/System` containing 59,490 (+ self) directories (and lots of files). | 
					
						
							|  |  |  | The size of the text output was 6mb. | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | `find`: | 
					
						
							|  |  |  |     time bash -c "find /System -type d | wc" | 
					
						
							|  |  |  |     59491   97935 6262916 | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  |     real  2m27.114s | 
					
						
							|  |  |  |     user  0m1.193s | 
					
						
							|  |  |  |     sys 0m14.859s | 
					
						
							| 
									
										
										
										
											2010-11-20 22:02:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07:00
										 |  |  | `find.js`: | 
					
						
							| 
									
										
										
										
											2010-12-02 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 01:58:43 -07: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 03:09:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-02 21:11:03 -06:00
										 |  |  | In conclusion node.js asynchronous walk is much slower than regular "find". | 
					
						
							| 
									
										
										
										
											2012-05-08 09:57:33 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | LICENSE | 
					
						
							|  |  |  | === | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `node-walk` is available under the following licenses: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   * MIT | 
					
						
							|  |  |  |   * Apache 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Copyright 2011 - Present AJ ONeal |