Inspired by the top rated answer on this question: node.js fs.readdir recursive directory search, I have been trying to refactor the answer into a readable stream. No luck so far.
It seems like its running an endless recursion.
var stream = require('stream');
var Readable = stream.Readable;
var util = require('util');
util.inherits(Images, Readable);
function Images(images_dir, opt) {
Readable.call(this, opt);
this.images_dir= images_dir;
this.pending = 1;
}
Images.prototype._read = function() {
var that = this;
this.walk(this.images_dir, function(err, file) {
if(err) {throw err;}
that.pending--;
if(that.pending == 0) {
console.log('done');
//that.push(null);
}
});
};
Images.prototype.walk = function(dir, done) {
var that = this;
console.log('pending: ' + that.pending + ', scanning dir ' + dir);
fs.readdir(dir, function(err, list) {
if (err) return done(err);
that.pending += list.length;
list.forEach(function(file_or_dir, index) {
file_or_dir = dir + '/' + file_or_dir;
fs.stat(file_or_dir, function(err, stat) {
if (err) return done(err);
if (stat && stat.isDirectory()) {
that.walk(file_or_dir, done);
} else {
//that.push(file_or_dir);
console.log('pending: ' + that.pending + ', sending file ' + file_or_dir);
return done(null);
}
});
if(index == (list.length - 1)) {
return done(null);
}
});
});
};
var images = new Images(images_dir);
images.pipe(process.stdout);
UPDATE: I have updated the code to show that it works with console logs, but it does not when I use the push function. Just uncomment the push functions and it will run for ever.
SOLUTION: I have moved the recursive call to this.walk to the Images constructor. This means that the the file paths get bufferd in the stream until the a consumer gets connected. It would still be better to define a _read function (https://github.com/substack/stream-handbook#creating-a-readable-stream). But just not in this manner.