获取目录nodejs中的所有目录

我希望这将是一件简单的事情,但我找不到任何东西。

我只想获取给定文件夹/目录中的所有文件夹/目录。

举个例子:

<MyFolder> |- SomeFolder |- SomeOtherFolder |- SomeFile.txt |- SomeOtherFile.txt |- x-directory 

我希望得到一个数组:

 ["SomeFolder", "SomeOtherFolder", "x-directory"] 

或者上面的道路,如果这是如何服务…

那么,现在有什么东西可以做到这一点?

下面是这个答案的一个简短的同步版本,可以列出当前目录中的所有目录(隐藏或不隐藏):

 const { lstatSync, readdirSync } = require('fs') const { join } = require('path') const isDirectory = source => lstatSync(source).isDirectory() const getDirectories = source => readdirSync(source).map(name => join(source, name)).filter(isDirectory) 

由于箭头function(ES6),它几乎是一条线:

 const fs = require('fs') const path = require('path') const dirs = p => fs.readdirSync(p).filter(f => fs.statSync(path.join(p, f)).isDirectory()) 

这应该做到这一点:

CoffeeScript(同步)

 fs = require 'fs' getDirs = (rootDir) -> files = fs.readdirSync(rootDir) dirs = [] for file in files if file[0] != '.' filePath = "#{rootDir}/#{file}" stat = fs.statSync(filePath) if stat.isDirectory() dirs.push(file) return dirs 

CoffeeScript(asynchronous)

 fs = require 'fs' getDirs = (rootDir, cb) -> fs.readdir rootDir, (err, files) -> dirs = [] for file, index in files if file[0] != '.' filePath = "#{rootDir}/#{file}" fs.stat filePath, (err, stat) -> if stat.isDirectory() dirs.push(file) if files.length == (index + 1) cb(dirs) 

JavaScript(asynchronous)

 var fs = require('fs'); var getDirs = function(rootDir, cb) { fs.readdir(rootDir, function(err, files) { var dirs = []; for (var index = 0; index < files.length; ++index) { var file = files[index]; if (file[0] !== '.') { var filePath = rootDir + '/' + file; fs.stat(filePath, function(err, stat) { if (stat.isDirectory()) { dirs.push(this.file); } if (files.length === (this.index + 1)) { return cb(dirs); } }.bind({index: index, file: file})); } } }); } 

使用path列出目录。

 function getDirectories(path) { return fs.readdirSync(path).filter(function (file) { return fs.statSync(path+'/'+file).isDirectory(); }); } 

和asynchronous版本的getDirectories,你需要这个asynchronous模块 :

 var fs = require('fs'); var path = require('path'); var async = require('async'); // https://github.com/caolan/async // Original function function getDirsSync(srcpath) { return fs.readdirSync(srcpath).filter(function(file) { return fs.statSync(path.join(srcpath, file)).isDirectory(); }); } function getDirs(srcpath, cb) { fs.readdir(srcpath, function (err, files) { if(err) { console.error(err); return cb([]); } var iterator = function (file, cb) { fs.stat(path.join(srcpath, file), function (err, stats) { if(err) { console.error(err); return cb(false); } cb(stats.isDirectory()); }) } async.filter(files, iterator, cb); }); } 

或者,如果您可以使用外部库,则可以使用filehound 。 它支持callback,承诺和同步呼叫。

使用承诺:

 const Filehound = require('filehound'); Filehound.create() .path("MyFolder") .directory() // only search for directories .find() .then((subdirectories) => { console.log(subdirectories); }); 

使用callback:

 const Filehound = require('filehound'); Filehound.create() .path("MyFolder") .directory() .find((err, subdirectories) => { if (err) return console.error(err); console.log(subdirectories); }); 

同步通话:

 const Filehound = require('filehound'); const subdirectories = Filehound.create() .path("MyFolder") .directory() .findSync(); console.log(subdirectories); 

有关更多信息(和示例),请查看文档: https : //github.com/nspragg/filehound

免责声明:我是作者。

我会亲自将循环中的stat函数声明为这样的:

 function getSubDirs(dir, cb) { fs.readdir(dir, function(err, files) { var dirs = [], filePath, checkDirectory = function(err, stat) { if(stat.isDirectory()) { dirs.push(files[i]); } if(i + 1 === l) { // last record cb(dirs); } }; for(var i=0, l=files.length; i<l; i++) { if(files[i][0] !== '.') { // ignore hidden filePath = dir+'/'+files[i]; fs.stat(filePath, checkDirectory); } } }); } 

JShint抱怨,否则,你可能会创build一个新的函数调用每个循环传递。

recursion解决scheme

我来到这里寻找一种方法来获得所有的子目录,以及所有的子目录等。基于接受的答案 ,我写了这样的:

 const shell = require('shelljs'); const fs = require('fs'); const path = require('path'); function flatten(lists) { return lists.reduce(function(a, b) { return a.concat(b); }, []); } function getDirectories(srcpath) { return fs.readdirSync(srcpath) .map(file => path.join(srcpath, file)) .filter(path => fs.statSync(path).isDirectory()); } function getDirectoriesRecursive(srcpath) { return [srcpath, ...flatten(getDirectories(srcpath).map(getDirectoriesRecursive))]; } 

此答案的 CoffeeScript版本,具有适当的error handling:

 fs = require "fs" {join} = require "path" async = require "async" get_subdirs = (root, callback)-> fs.readdir root, (err, files)-> return callback err if err subdirs = [] async.each files, (file, callback)-> fs.stat join(root, file), (err, stats)-> return callback err if err subdirs.push file if stats.isDirectory() callback null (err)-> return callback err if err callback null, subdirs 

取决于asynchronous

或者, 使用这个模块! (有一切的模块。[引文需要])

为了防止任何人从networkingsearch结果到这里,并且已经在其依赖列表中find了Grunt,对此的回答就变得微不足道了。 这是我的解决scheme:

 /** * Return all the subfolders of this path * @param {String} parentFolderPath - valid folder path * @param {String} glob ['/*'] - optional glob so you can do recursive if you want * @returns {String[]} subfolder paths */ getSubfolders = (parentFolderPath, glob = '/*') => { return grunt.file.expand({filter: 'isDirectory'}, parentFolderPath + glob); } 

如果你需要使用所有的async版本。 你可以有这样的事情。

  1. logging目录的长度,用它作为一个指标来判断是否所有的asynchronous统计任务都完成了。

  2. 如果asynchronous统计任务完成,所有文件统计已被检查,所以调用callback

这只会在Node.js是单线程的情况下工作,因为它假定没有两个asynchronous任务会同时增加计数器。

 'use strict'; var fs = require("fs"); var path = require("path"); var basePath = "./"; function result_callback(results) { results.forEach((obj) => { console.log("isFile: " + obj.fileName); console.log("fileName: " + obj.isFile); }); }; fs.readdir(basePath, (err, files) => { var results = []; var total = files.length; var finished = 0; files.forEach((fileName) => { // console.log(fileName); var fullPath = path.join(basePath, fileName); fs.stat(fullPath, (err, stat) => { // this will work because Node.js is single thread // therefore, the counter will not increment at the same time by two callback finished++; if (stat.isFile()) { results.push({ fileName: fileName, isFile: stat.isFile() }); } if (finished == total) { result_callback(results); } }); }); }); 

正如你所看到的,这是一个“深度优先”的方法,这可能会导致callback地狱,它不是很“function”。 人们试图用Promise解决这个问题,通过将asynchronous任务包装到Promise对象中。

 'use strict'; var fs = require("fs"); var path = require("path"); var basePath = "./"; function result_callback(results) { results.forEach((obj) => { console.log("isFile: " + obj.fileName); console.log("fileName: " + obj.isFile); }); }; fs.readdir(basePath, (err, files) => { var results = []; var total = files.length; var finished = 0; var promises = files.map((fileName) => { // console.log(fileName); var fullPath = path.join(basePath, fileName); return new Promise((resolve, reject) => { // try to replace fullPath wil "aaa", it will reject fs.stat(fullPath, (err, stat) => { if (err) { reject(err); return; } var obj = { fileName: fileName, isFile: stat.isFile() }; resolve(obj); }); }); }); Promise.all(promises).then((values) => { console.log("All the promise resolved"); console.log(values); console.log("Filter out folder: "); values .filter((obj) => obj.isFile) .forEach((obj) => { console.log(obj.fileName); }); }, (reason) => { console.log("Not all the promise resolved"); console.log(reason); }); }); 

使用fs,path模块可以得到文件夹。 这个用Promise。 如果你将得到填充,你可以改变isDirectory()isFile() Nodejs – fs – fs.Stats 。最后,你可以得到文件'name file'extname等Nodejs —path

 var fs = require("fs"), path = require("path"); //your <MyFolder> path var p = "MyFolder" fs.readdir(p, function (err, files) { if (err) { throw err; } //this can get all folder and file under <MyFolder> files.map(function (file) { //return file or folder path, such as **MyFolder/SomeFile.txt** return path.join(p, file); }).filter(function (file) { //use sync judge method. The file will add next files array if the file is directory, or not. return fs.statSync(file).isDirectory(); }).forEach(function (files) { //The files is array, so each. files is the folder name. can handle the folder. console.log("%s", files); }); });