Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS recursively list files in directory

I am trying to list all files in a directory (and files within any subdirectories) with the following code:

var fs = require('fs')

var walk = function(directoryName) {
  fs.readdir(directoryName, function(e, files) {
    files.forEach(function(file) {
      fs.stat(file, function(e, f) {
        if (f.isDirectory()) {
          walk(file)
        } else {
          console.log('- ' + file)
        }
      })
    })
  })
}

walk(__dirname)

However, when my code attempts to invoke walk(file) on line 8 I get the following error:

TypeError: Cannot call method 'isDirectory' of undefined
    at program.js:7:15
    at Object.oncomplete (fs.js:107:15)

Why is f undefined? If I have the directory structure below, shouldn't the code identify aaa.txt and bbb.txt as files, my_dir as a directory at which point it recursively calls walk and begins the process again (with zzz.txt being the value of f)?

- aaa.txt
- bbb.txt
+ my_dir
    - zzz.txt
like image 352
Iain Avatar asked Nov 09 '14 12:11

Iain


2 Answers

Function fs.readdir lists the simple file names in that directory, not their absolute path. This is why the program failed to find them, thus leading to an error in fs.stat.

Here's the solution: concatenate the directory path name to the file.

var fs = require('fs');
var path = require('path');

var walk = function(directoryName) {
  fs.readdir(directoryName, function(e, files) {
    if (e) {
      console.log('Error: ', e);
      return;
    }
    files.forEach(function(file) {
      var fullPath = path.join(directoryName,file);
      fs.stat(fullPath, function(e, f) {
        if (e) {
          console.log('Error: ', e);
          return;
        }
        if (f.isDirectory()) {
          walk(fullPath);
        } else {
          console.log('- ' + fullPath);
        }
      });
    });
  });
};
like image 123
E_net4 stands with Ukraine Avatar answered Oct 01 '22 19:10

E_net4 stands with Ukraine


var fs = require('fs');
var path = require('path');

var walk = function(directoryName) {

  fs.readdir(directoryName, function(e, files) {
    files.forEach(function(file) {
      fs.stat(directoryName + path.sep + file, function(e, f) {

        if (f.isDirectory()) {
          walk(directoryName + path.sep + file)
        } else {
          console.log(' - ' + file)
        }
      })
    })
  })
}

walk(__dirname)
like image 40
wayne Avatar answered Oct 01 '22 20:10

wayne