Implemented asynchronous recursive readdir #18

Merged
vgrichina merged 3 commits from master into master 2012-02-18 01:52:27 -08:00
6 changed files with 140 additions and 36 deletions

View file

@ -55,6 +55,70 @@ exports.readdirSyncRecursive = function(baseDir) {
return fileList;
};
/* wrench.readdirRecursive("directory_path", function(error, files) {});
*
* Recursively dives through directories and read the contents of all the
* children directories.
*
* Asynchronous, so returns results/error in callback.
* Callback receives the of files in currently recursed directory.
* When no more directories are left, callback is called with null for all arguments.
*
*/
exports.readdirRecursive = function(baseDir, fn) {
baseDir = baseDir.replace(/\/$/, '');
var waitCount = 0;
function readdirRecursive(curDir) {
var files = [],
curFiles,
nextDirs,
prependcurDir = function(fname){
return _path.join(curDir, fname);
};
waitCount++;
fs.readdir(curDir, function(e, curFiles) {
waitCount--;
curFiles = curFiles.map(prependcurDir);
curFiles.forEach(function(it) {
waitCount++;
fs.stat(it, function(e, stat) {
waitCount--;
if (e) {
fn(e);
} else {
if (stat.isDirectory()) {
readdirRecursive(it);
}
}
if (waitCount == 0) {
fn(null, null);
}
});
});
fn(null, curFiles.map(function(val) {
// convert absolute paths to relative
return val.replace(baseDir + '/', '');
}));
if (waitCount == 0) {
fn(null, null);
}
});
};
readdirRecursive(baseDir);
};
/* wrench.rmdirSyncRecursive("directory_path", forceDelete, failSilent);
*

View file

@ -18,7 +18,10 @@ Usage
``` javascript
var wrench = require('wrench'),
util = require('util');
```
### Synchronous operations
``` javascript
// Recursively create directories, sub-trees and all.
wrench.mkdirSyncRecursive(dir, 0777);
@ -43,6 +46,19 @@ while(f.hasNextLine()) {
util.puts(x.getNextLine());
}
```
It should be noted that these are all currently synchronous operations.
### Asynchronous operations
``` javascript
// Recursively read directories contents
var files = [];
wrench.readdirRecursive('my_directory_name', function(error, curFiles) {
if (files) {
files = files.concat(curFiles);
} else {
// files list contains all the directory contents now
}
});
```
Questions, comments? Hit me up. (ryan [at] venodesigns.net | http://twitter.com/ryanmcgrath)

57
tests/readdir.js Normal file
View file

@ -0,0 +1,57 @@
var testCase = require('nodeunit').testCase;
var fs = require('fs');
var wrench = require('../lib/wrench');
var path = require('path');
var _und = require("underscore");
function checkResult(test, files) {
var check = [
'bar.txt',
'foo',
'foo/bar',
'foo/dolor.md',
'foo/lorem.txt',
'foo/bar/ipsum.js'
];
test.equals(files.length, check.length, 'number of paths is correct');
_und.each(check, function(it) {
test.ok(_und.include(files, it), 'path ' + it + ' should be returned');
});
test.done();
}
module.exports = testCase({
test_readdirSyncRecursive: function(test) {
var dir = __dirname + '/readdir';
test.ok(path.existsSync(dir), 'Folders should exist');
var files = wrench.readdirSyncRecursive(dir);
checkResult(test, files);
},
test_readdirRecursive: function(test) {
var dir = __dirname + '/readdir';
test.ok(path.existsSync(dir), 'Folders should exist');
var allFiles = [];
wrench.readdirRecursive(dir, function(e, files) {
if (e) throw e;
if (files) {
allFiles = allFiles.concat(files);
} else {
checkResult(test, allFiles);
}
});
}
});
// vim: et ts=4 sw=4

View file

@ -1,33 +0,0 @@
var testCase = require('nodeunit').testCase;
var fs = require('fs');
var wrench = require('../lib/wrench');
var path = require('path');
var _und = require("underscore");
module.exports = testCase({
test_readdirSyncRecursive: function(test) {
var dir = __dirname + '/readdir';
test.equals(path.existsSync(dir), true, 'Folders should exist');
var check = [
'bar.txt',
'foo',
'foo/bar',
'foo/dolor.md',
'foo/lorem.txt',
'foo/bar/ipsum.js'
];
var files = wrench.readdirSyncRecursive(dir);
test.equals(files.length, check.length, 'number of paths is correct');
for (var filename in files) {
test.ok(_und.include(check, files[filename]));
}
test.done();
}
});
// vim: et ts=4 sw=4

View file

@ -2,6 +2,6 @@
// will run all the tests
module.exports = {
group_mkdirSyncRecursive : require('./mkdirSyncRecursive'),
group_readdirSyncRecursive : require('./readdirSyncRecursive')
group_mkdir: require('./mkdir'),
group_readdir: require('./readdir')
};