获取目录nodejs中的所有目录

Gro*_*fit 230 directory node.js

我希望这会是一件简单的事情,但我找不到任何可以做到的事情.

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

例如:

<MyFolder>
|- SomeFolder
|- SomeOtherFolder
|- SomeFile.txt
|- SomeOtherFile.txt
|- x-directory
Run Code Online (Sandbox Code Playgroud)

我希望得到一个数组:

["SomeFolder", "SomeOtherFolder", "x-directory"]
Run Code Online (Sandbox Code Playgroud)

或上面的路径,如果这是如何服务...

那么上面有什么已经存在的吗?

Nic*_*rdy 403

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

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)
Run Code Online (Sandbox Code Playgroud)

  • 小心,你需要absolut路径来获取文件统计信息.``require('path').resolve(__ dirname,file)`` (14认同)
  • @pilau它只是不适用于相对路径,这就是为什么你需要规范化它.为此,您可以使用path.resolve. (9认同)
  • 因为你正在使用es6:`const getDirectories = srcPath => fs.readdirSync(srcPath).filter(file => fs.statSync(path.join(srcPath,file)).isDirectory())` (5认同)
  • 请注意,如果目录中存在符号链接,则会中断.请改用`lstatSync`. (2认同)

pra*_*mil 93

感谢JavaScript ES6(ES2015)语法功能,它是一个内容:

**同步版**

const { readdirSync, statSync } = require('fs')
const { join } = require('path')

const dirs = p => readdirSync(p).filter(f => statSync(join(p, f)).isDirectory())
Run Code Online (Sandbox Code Playgroud)

Node.js 10+的异步版本(实验性)

const { readdir, stat } = require("fs").promises
const { join } = require("path")

const dirs = async path => {
  let dirs = []
  for (const file of await readdir(path)) {
    if ((await stat(join(path, file))).isDirectory()) {
      dirs = [...dirs, file]
    }
  }
  return dirs
}
Run Code Online (Sandbox Code Playgroud)

  • Upvoted.尽管有人批评它应该分散在更多的界限上.这个答案展示了新语法的语义优势,但我认为人们会因为它被挤在一条线上而分心.如果将此代码扩展到与接受的答案相同的行数,则它仍然是相同机制的更简洁表达.我认为这个答案有一些价值,但也许它应该是对已接受答案的编辑,而不是一个明确的答案. (26认同)
  • 将某些东西强加到一行会使其不易读取,因此不太理想. (25认同)
  • 你们认真吗?这是一个非常好的和有效的答案!一条线,抄袭 - 希望有一种方法可以贬低糟糕的借口.这不是火箭科学.这是一个非常简单和愚蠢的操作!不要为了它而冗长!肯定得到我的+1! (19认同)
  • @DenysSéguret我只是让代码更清晰 (13认同)
  • 你可以在一行上放任何指令,但这并不意味着你应该. (5认同)
  • Upvoted.不确定为什么人们对此进行了贬低.一个班轮很糟糕但很简单,你可以按照自己的意愿美化它.关键是你从这个答案中学到了一些东西 (3认同)
  • 我建议的唯一变化是使用`path.join(p,f)`而不是`p +"/"+ f`来使它在不同的操作系统中更加健壮. (3认同)
  • 请不要命名变量“ p”,“ f”或任何其他单个字母,只是为了缩短代码长度。 (2认同)

小智 26

使用路径列出目录.

function getDirectories(path) {
  return fs.readdirSync(path).filter(function (file) {
    return fs.statSync(path+'/'+file).isDirectory();
  });
}
Run Code Online (Sandbox Code Playgroud)


Pat*_*ney 19

递归解决方案

我来到这里寻找一种方法来获取所有子目录及其所有子目录等.基于接受的答案,我写道:

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

function flatten(lists) {
  return lists.reduce((a, b) => 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))];
}
Run Code Online (Sandbox Code Playgroud)

  • 一种不那么脏的方法是 path.normalize()。https://nodejs.org/api/path.html#path_path_normalize_path (2认同)

nic*_*eet 10

这应该这样做:

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
Run Code Online (Sandbox Code Playgroud)

CoffeeScript(异步)

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)
Run Code Online (Sandbox Code Playgroud)

JavaScript(异步)

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})); 
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • Ug,人们需要停止诋毁同步api.确定是否应该使用同步版本不是由"生产"确定的.同样重复广告,即async api更好,同步很糟糕,没有上下文,这是不准确的.我希望JS社区不要再发布这个了.同步更简单(yay)但会阻止消息循环(boo).因此,不要在您不想阻止的服务器中使用sync api,而是可以在构建脚本中使用它们,例如无关紧要的情况.</咆哮> (21认同)
  • 请注意阅读这个答案的任何新手:这是CoffeeScript,而不是JavaScript(我的朋友在混乱中告诉我,为什么JavaScript突然有语义空白). (20认同)

小智 6

或者,如果您能够使用外部库,则可以使用filehound.它支持回调,承诺和同步调用.

使用承诺:

const Filehound = require('filehound');

Filehound.create()
  .path("MyFolder")
  .directory() // only search for directories
  .find()
  .then((subdirectories) => {
    console.log(subdirectories);
  });
Run Code Online (Sandbox Code Playgroud)

使用回调:

const Filehound = require('filehound');

Filehound.create()
  .path("MyFolder")
  .directory()
  .find((err, subdirectories) => {
    if (err) return console.error(err);

    console.log(subdirectories);
  });
Run Code Online (Sandbox Code Playgroud)

同步通话:

const Filehound = require('filehound');

const subdirectories = Filehound.create()
  .path("MyFolder")
  .directory()
  .findSync();

console.log(subdirectories);
Run Code Online (Sandbox Code Playgroud)

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

免责声明:我是作者.


May*_*yur 6

对于 node.js 版本 >= v10.13.0,如果选项设置为,fs.readdirSync将返回一个fs.Dirent对象数组。withFileTypestrue

所以你可以使用,

const fs = require('fs')

const directories = source => fs.readdirSync(source, {
   withFileTypes: true
}).reduce((a, c) => {
   c.isDirectory() && a.push(c.name)
   return a
}, [])
Run Code Online (Sandbox Code Playgroud)

  • 是的,我仍然更喜欢 `.filter(c =&gt; c.isDirectory()).map(c =&gt; c.name)` 而不是 `reduce` 调用。 (3认同)

1mi*_*e12 5

使用 fs-extra,它承诺异步 fs 调用,以及新的 await 异步语法:

const fs = require("fs-extra");

async function getDirectories(path){
    let filesAndDirectories = await fs.readdir(path);

    let directories = [];
    await Promise.all(
        filesAndDirectories.map(name =>{
            return fs.stat(path + name)
            .then(stat =>{
                if(stat.isDirectory()) directories.push(name)
            })
        })
    );
    return directories;
}

let directories = await getDirectories("/")
Run Code Online (Sandbox Code Playgroud)


小智 5

 var getDirectories = (rootdir , cb) => {
    fs.readdir(rootdir, (err, files) => {
        if(err) throw err ;
        var dirs = files.map(filename => path.join(rootdir,filename)).filter( pathname => fs.statSync(pathname).isDirectory());
        return cb(dirs);
    })

 }
 getDirectories( myDirectories => console.log(myDirectories));``
Run Code Online (Sandbox Code Playgroud)