受到关于这个问题的最高评价答案的启发:node.js fs.readdir recursive directory search,我一直试图将答案重构为可读流。到目前为止没有运气。
似乎它正在进行无休止的递归。
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);
更新:我已更新代码以显示它与控制台日志一起使用,但是当我使用push函数时它不会。只需取消注释推送功能,它就会永远运行。
解决方案:我已将对this.walk的递归调用移至Images构造函数。这意味着文件路径在流中缓冲,直到消费者连接为止。定义_read函数(https://github.com/substack/stream-handbook#creating-a-readable-stream)仍然会更好。但就是这样。