1

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.

Community
  • 1
  • 1
Erik
  • 307
  • 1
  • 9
  • This is probably unrelated, but you're completely ignoring errors. For example, you probably shouldn't `push(file)` if `fs.stat()` resulted in error. You're also ignoring errors in `that.walk()`. – mscdex Sep 23 '14 at 21:51
  • You're right, I'll fix that! – Erik Sep 23 '14 at 22:03

0 Answers0