最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - NodeJS recursively list files in directory - Stack Overflow

programmeradmin2浏览0评论

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.onplete (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

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.onplete (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
Share Improve this question asked Nov 9, 2014 at 12:01 IainIain 1,7346 gold badges24 silver badges39 bronze badges 2
  • 2 Try testing for e, there might have been an error. – E_net4 Commented Nov 9, 2014 at 12:07
  • 1 you need to add you directoryName to the recursive walk as well. – wayne Commented Nov 9, 2014 at 12:48
Add a ment  | 

4 Answers 4

Reset to default 8

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);
        }
      });
    });
  });
};
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)

Here's a version for async/await:

const { promises: fs } = require("fs");
const path = require("path");

async function walk(dir) {
    const entries = await fs.readdir(dir);
    let ret = [];
    for (const entry of entries) {
        const fullpath = path.resolve(dir, entry);
        const info = await fs.stat(fullpath);
        if (info.isDirectory()) {
            ret = [...ret, ...(await walk(fullpath))];
        } else {
            ret = [...ret, fullpath];
        }
    }
    return ret;
}

(async function () {
    console.log(await walk("/path/to/some/dir"));
})();

A fully synchronous version, for those situations where you cannot use async:

const walk = (dir, files = []) => {
    const dirFiles = fs.readdirSync(dir)
    for (const f of dirFiles) {
        const stat = fs.lstatSync(dir + path.sep + f)
        if (stat.isDirectory()) {
            walk(dir + path.sep + f, files)
        } else {
            files.push(dir + path.sep + f)
        }
    }
    return files
}
const allFiles = walk(someDir)
发布评论

评论列表(0)

  1. 暂无评论