รับไดเร็กทอรีทั้งหมดภายในไดเร็กทอรี nodejs


260

ฉันหวังว่านี่จะเป็นสิ่งที่เรียบง่าย แต่ฉันไม่สามารถหาอะไรทำที่นั่น

ฉันต้องการรับโฟลเดอร์ / ไดเรกทอรีทั้งหมดภายในโฟลเดอร์ / ไดเรกทอรีที่ระบุ

ตัวอย่างเช่น:

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

ฉันคาดว่าจะได้รับอาร์เรย์:

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

หรือเหนือด้วยเส้นทางถ้าเป็นวิธีที่มันเสิร์ฟ ...

ดังนั้นมีอยู่แล้วที่จะทำข้างต้น?

คำตอบ:


463

ต่อไปนี้เป็นคำตอบที่สั้นลงและตรงกับเวอร์ชันซึ่งสามารถแสดงรายการไดเรกทอรีทั้งหมด (ซ่อนอยู่หรือไม่) ในไดเรกทอรีปัจจุบัน:

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)

อัพเดทสำหรับ Node 10.10.0+

เราสามารถใช้withFileTypesตัวเลือกใหม่ของreaddirSyncการข้ามlstatSyncสายพิเศษ:

const { readdirSync } = require('fs')

const getDirectories = source =>
  readdirSync(source, { withFileTypes: true })
    .filter(dirent => dirent.isDirectory())
    .map(dirent => dirent.name)

14
ระวังคุณต้องใช้พา ธ สัมบูรณ์เพื่อรับค่าสถิติไฟล์ require('path').resolve(__dirname, file)
สีลม

9
@pilau มันใช้ไม่ได้กับเส้นทางที่เป็นญาตินั่นเป็นเหตุผลว่าทำไมคุณต้องทำให้มันเป็นมาตรฐาน เพื่อให้คุณสามารถใช้ path.resolve
สีลม

1
@rickysullivan: คุณต้องทำซ้ำผ่านการตอบสนองและใช้ path.resolve (srcpath, foldername) สำหรับแต่ละโฟลเดอร์ภายใน
jarodsmk

5
เนื่องจากคุณใช้ es6:const getDirectories = srcPath => fs.readdirSync(srcPath).filter(file => fs.statSync(path.join(srcPath, file)).isDirectory())
pmrotule

2
หมายเหตุตัวแบ่งนี้ถ้ามี symlink ในไดเรกทอรี ใช้lstatSyncแทน
เดฟ

103

ต้องขอบคุณคุณสมบัติทางไวยากรณ์ของ JavaScript ES6 (ES2015) ที่เป็นหนึ่งในสายการบิน:

รุ่นซิงโครนัส

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

const dirs = p => readdirSync(p).filter(f => statSync(join(p, f)).isDirectory())

เวอร์ชันอะซิงโครนัสสำหรับ 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
}

30
การบังคับบางอย่างให้กับบรรทัดเดียวทำให้อ่านได้น้อยลงและต้องการน้อยลง
rlemon

7
คุณสามารถใส่คำแนะนำในบรรทัดเดียวไม่ได้หมายความว่าคุณควรทำ
Kevin B

4
upvoted ไม่แน่ใจว่าทำไมคนลงคะแนนนี้ สายการบินหนึ่งที่ไม่ดี แต่ comon คุณสามารถตกแต่งได้ตามที่คุณต้องการ ประเด็นก็คือคุณได้เรียนรู้บางสิ่งจากคำตอบนี้
Aamir Afridi

27
upvoted แม้ว่ามันจะเป็นคำวิจารณ์ที่ถูกต้องว่ามันควรจะกระจายไปทั่วเส้นมากขึ้น คำตอบนี้แสดงให้เห็นถึงความได้เปรียบทางความหมายของไวยากรณ์ใหม่ แต่ฉันคิดว่าผู้คนกำลังถูกรบกวนโดยวิธีที่มันยัดเยียดให้อยู่ในบรรทัดเดียว หากคุณกระจายรหัสนี้ในจำนวนบรรทัดเดียวกันกับคำตอบที่ยอมรับก็ยังคงเป็นการแสดงออกที่กระชับยิ่งขึ้นของกลไกเดียวกัน ฉันคิดว่าคำตอบนี้มีค่าบางอย่าง แต่บางทีมันก็สมควรที่จะแก้ไขคำตอบที่ยอมรับได้มากกว่าคำตอบที่ชัดเจน
ผู้ช่วยให้รอดเหล็ก

23
คุณเป็นคนจริงจังหรือเปล่า นี่เป็นคำตอบที่สมบูรณ์และสมบูรณ์แบบ! หนึ่งบรรทัดคัดลอกผลงาน - หวังว่าจะมีวิธีแก้ตัวหมัดที่แย่ลง นี่ไม่ใช่วิทยาศาสตร์จรวด มันง่ายมากและเป็นใบ้! อย่า verbose เพื่อประโยชน์ของมัน! รับ +1 ของฉันอย่างแน่นอน!
Mrchief

36

รายการไดเรกทอรีโดยใช้เส้นทาง

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

1
อันนี้ตรงไปตรงมาสวย
Paula Fleck

ในที่สุดฉันก็เข้าใจ
FourCinnamon0

21

โซลูชันแบบเรียกซ้ำ

ฉันมาที่นี่เพื่อค้นหาวิธีรับไดเรกทอรีย่อยทั้งหมดและไดเรกทอรีย่อยทั้งหมด ฯลฯ สร้างคำตอบที่ยอมรับฉันเขียนสิ่งนี้:

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

นี่คือสิ่งที่ฉันกำลังมองหาและดูเหมือนว่าจะทำงานได้ดียกเว้นว่าทุกเส้นทางยกเว้นเส้นทางแรกที่ปรากฏเช่นนี้: "src \\ pages \\ partials \\ ปุ่ม" แทนที่จะเป็น "src / pages / partials / buttons" . ฉันเพิ่มโปรแกรมแก้ไขสกปรกนี้: var res = getDirectoriesRecursive (srcpath); res = res.map (ฟังก์ชั่น (x) {return x.replace (/ \\ / g, "/")}); console.log (Res);
PaulB

1
วิธีที่สกปรกน้อยกว่าในการทำเช่นนั้นคือ path.n ปกติize () nodejs.org/api/path.html#path_path_normalize_path
Patrick McElhaney

คุณกำลังส่งคืนไดเร็กทอรีพาเรนต์ซึ่งไม่ต้องการ ฉันจะ refactor getDirectoriesRecursive เพื่อป้องกันไม่ให้: if (recursive) return [srcpath, ...flatten(getDirectories(srcpath).map(getDirectoriesRecursive))]; else return [...flatten(getDirectories(srcpath).map(getDirectoriesRecursive))]; }
Nadav

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

CoffeeScript (async)

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 (async)

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

1
แม้ว่านี่จะเป็นระบบที่ใช้งานจริง แต่คุณต้องการหลีกเลี่ยงfsวิธีการแบบซิงโครนัส
Aaron Dufour

20
หมายเหตุถึงมือใหม่ที่อ่านคำตอบนี้: นี่คือ CoffeeScript ไม่ใช่ JavaScript (เพื่อนของฉันทำให้ฉันสับสนเพราะถามว่าทำไมจาวาสคริปต์ถึงมีช่องว่างความหมาย)
DallonF

1
@nicksweet คุณสามารถแปลงเป็น JS ได้ไหม?
mikemaccana

1
มีปัญหาบางอย่างที่จ้องมองกับคำตอบนี้: มันไม่มีการจัดการข้อผิดพลาดใด ๆ ; (ลายเซ็นการโทรกลับควรเป็น(err, dirs)) มันจะไม่โทรกลับในที่ที่มีไฟล์ dot หรือโฟลเดอร์อยู่ มันไวต่อสภาพการแข่งขันทั้งหมด; มันอาจโทรกลับก่อนที่จะตรวจสอบรายการทั้งหมด
1j01

21
เออคนต้องหยุดการซิงค์ API การพิจารณาว่าควรใช้เวอร์ชันซิงค์หรือไม่นั้นไม่ได้พิจารณาว่าเป็น "การผลิต" นอกจากนี้การทำซ้ำคลื่นไส้โฆษณาที่ async api นั้นดีกว่าและการซิงค์ไม่ดีโดยไม่มีบริบทนั้นไม่ถูกต้อง ฉันหวังว่าชุมชน JS จะหยุดการประกาศนี้ การซิงค์นั้นง่ายกว่า (ใช่) แต่จะบล็อกการวนรอบข้อความ (boo) ดังนั้นอย่าใช้ API การซิงค์ในเซิร์ฟเวอร์ที่คุณไม่ต้องการบล็อก แต่อย่าลังเลที่จะใช้มันในสคริปต์การสร้างตัวอย่างที่ไม่สำคัญ </rant>
hcoverlambda

6

filehoundหรือถ้าคุณสามารถที่จะใช้ห้องสมุดภายนอกคุณสามารถใช้ รองรับการโทรกลับสัญญาและซิงค์การโทร

ใช้สัญญา:

const Filehound = require('filehound');

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

ใช้โทรกลับ:

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

คำเตือน: ฉันเป็นผู้เขียน


5

กับรุ่น 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
}, [])

จุดดี แต่.filter(c => c.isDirectory())จะง่ายกว่าการใช้reduce()
Emmanuel Touzery

ใช่ แต่ตัวกรองส่งคืนอาร์เรย์ของวัตถุ fs.Dirent ซึ่งเป็นไดเรกทอรี OP ต้องการชื่อไดเรกทอรี
Mayur

1
จริงฉันยังคงต้องการ.filter(c => c.isDirectory()).map(c => c.name)มากกว่าการreduceโทรแม้ว่า
Emmanuel Touzery

ฉันเห็นประเด็นของคุณ ฉันเดาว่าผู้อ่าน SO สามารถตัดสินใจได้ตามกรณีการใช้งานของพวกเขา ฉันจะบอกว่าการวนลูปมากกว่าอาเรย์ในหน่วยความจำควรมีค่าใช้จ่ายเล็กน้อยเมื่อเทียบกับ I / O ของการอ่านจากดิสก์แม้ว่าคุณกำลังอ่านจาก SSD แต่ตามปกติถ้าใครสนใจจริงๆพวกเขาสามารถวัดได้
Emmanuel Touzery

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

4

ใช้ fs-extra ซึ่งสัญญาว่าจะเรียก async fs และไวยากรณ์ async ใหม่ที่รอคอย:

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("/")

3

และเวอร์ชัน async ของ getDirectories คุณต้องมีโมดูล asyncสำหรับสิ่งนี้:

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

2

คำตอบนี้ไม่ได้ใช้การปิดกั้นการทำงานเช่นการหรือreaddirSync statSyncมันไม่ได้ใช้การพึ่งพาจากภายนอกหรือค้นหาตัวเองในส่วนลึกของนรกโทรกลับ

แต่เราใช้สิ่งอำนวยความสะดวก JavaScript ที่ทันสมัยเช่นสัญญาและasync-awaitไวยากรณ์ และผลลัพธ์แบบอะซิงโครนัสจะถูกประมวลผลแบบขนาน ไม่ต่อเนื่อง -

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

const { join } =
  require ("path")

const dirs = async (path = ".") =>
  (await stat (path)) .isDirectory ()
    ? Promise
        .all
          ( (await readdir (path))
              .map (p => dirs (join (path, p)))
          )
        .then
          ( results =>
              [] .concat (path, ...results)
          )
    : []

ฉันจะติดตั้งแพคเกจตัวอย่างแล้วทดสอบฟังก์ชั่นของเรา -

$ npm install ramda
$ node

มาดูกันดีกว่า -

> dirs (".") .then (console.log, console.error)

[ '.'
, 'node_modules'
, 'node_modules/ramda'
, 'node_modules/ramda/dist'
, 'node_modules/ramda/es'
, 'node_modules/ramda/es/internal'
, 'node_modules/ramda/src'
, 'node_modules/ramda/src/internal'
]

การใช้โมดูลทั่วไปParallelเราสามารถทำให้คำจำกัดความของdirs-

const Parallel =
  require ("./Parallel")

const dirs = async (path = ".") =>
  (await stat (path)) .isDirectory ()
    ? Parallel (readdir (path))
        .flatMap (f => dirs (join (path, f)))
        .then (results => [ path, ...results ])
    : []

Parallelโมดูลสินค้าด้านบนเป็นรูปแบบที่ถูกสกัดจากชุดของฟังก์ชั่นที่ออกแบบมาเพื่อแก้ปัญหาที่คล้ายกัน สำหรับคำอธิบายเพิ่มเติมโปรดดูคำถาม & คำตอบที่เกี่ยวข้อง


1

เวอร์ชัน CoffeeScript ของคำตอบนี้พร้อมการจัดการข้อผิดพลาดที่เหมาะสม:

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

ขึ้นอยู่กับasync

หรือใช้โมดูลสำหรับสิ่งนี้! (มีโมดูลสำหรับทุกสิ่ง [ต้องการอ้างอิง])


1

หากคุณจำเป็นต้องใช้ทุกasyncรุ่น คุณสามารถมีอะไรเช่นนี้

  1. บันทึกความยาวของไดเรกทอรีใช้เป็นตัวบ่งชี้เพื่อบอกว่างาน async stat ทั้งหมดเสร็จสิ้นหรือไม่

  2. หากงานสถิติ async เสร็จสิ้นสถานะไฟล์ทั้งหมดจะถูกตรวจสอบดังนั้นให้โทรติดต่อกลับ

สิ่งนี้จะทำงานได้ตราบใดที่ Node.js เป็นเธรดเดียวเนื่องจากถือว่าไม่มีงานใด ๆ ของ async สองงานที่จะเพิ่มตัวนับในเวลาเดียวกัน

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

อย่างที่คุณเห็นนี่เป็นวิธี "ความลึกอันดับแรก" และนี่อาจส่งผลให้เกิดการเรียกกลับนรกและมันก็ไม่ได้ "ทำงาน" ได้ ผู้คนพยายามที่จะแก้ปัญหานี้ด้วยสัญญาโดยห่อภารกิจ async ไว้ในวัตถุสัญญา

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

รหัสที่ดี! แต่ฉันคิดว่ามันควรจะเป็น "Filter out files:" ใน Promise.all block เพราะมันกำลังตรวจสอบว่ามันเป็นไฟล์และทำการบันทึกมันหรือไม่ :)
Bikal Nepal

1

ใช้โมดูลเส้นทาง fs、สามารถรับโฟลเดอร์ สัญญานี้ใช้ หากคุณจะได้รับการเติมคุณสามารถเปลี่ยนisDirectory ()เป็นisFile () Nodejs - fs - fs.Stats . ในที่สุดคุณจะได้รับ file'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);
    });
});

จากคิวการตรวจทาน:ฉันขอให้คุณเพิ่มบริบทเพิ่มเติมเกี่ยวกับคำตอบของคุณได้ไหม คำตอบแบบรหัสเท่านั้นยากที่จะเข้าใจ มันจะช่วยผู้ถามและผู้อ่านในอนาคตทั้งสองหากคุณสามารถเพิ่มข้อมูลเพิ่มเติมในโพสต์ของคุณ
help-info.de

1

เวอร์ชันอะซิงก์ทั้งหมดพร้อม ES6, เฉพาะแพ็คเกจดั้งเดิม, fs.promises และ async / await, ดำเนินการกับไฟล์แบบขนาน:

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

async function listDirectories(rootPath) {
    const fileNames = await fs.promises.readdir(rootPath);
    const filePaths = fileNames.map(fileName => path.join(rootPath, fileName));
    const filePathsAndIsDirectoryFlagsPromises = filePaths.map(async filePath => ({path: filePath, isDirectory: (await fs.promises.stat(filePath)).isDirectory()}))
    const filePathsAndIsDirectoryFlags = await Promise.all(filePathsAndIsDirectoryFlagsPromises);
    return filePathsAndIsDirectoryFlags.filter(filePathAndIsDirectoryFlag => filePathAndIsDirectoryFlag.isDirectory)
        .map(filePathAndIsDirectoryFlag => filePathAndIsDirectoryFlag.path);
}

ผ่านการทดสอบมันใช้งานได้ดี


0

ในกรณีที่คนอื่นมาที่นี่จากการค้นหาเว็บและมี Grunt อยู่แล้วในรายการพึ่งพาของพวกเขาคำตอบสำหรับเรื่องนี้กลายเป็นเรื่องเล็กน้อย นี่คือทางออกของฉัน:

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

0

อีกวิธีเรียกซ้ำ

ขอขอบคุณที่ Mayur withFileTypesการรู้ฉันเกี่ยวกับ ฉันเขียนโค้ดต่อไปนี้เพื่อรับไฟล์ของโฟลเดอร์เฉพาะแบบวนซ้ำ สามารถแก้ไขได้อย่างง่ายดายเพื่อรับเฉพาะไดเรกทอรี

const getFiles = (dir, base = '') => readdirSync(dir, {withFileTypes: true}).reduce((files, file) => {
    const filePath = path.join(dir, file.name)
    const relativePath = path.join(base, file.name)
    if(file.isDirectory()) {
        return files.concat(getFiles(filePath, relativePath))
    } else if(file.isFile()) {
        file.__fullPath = filePath
        file.__relateivePath = relativePath
        return files.concat(file)
    }
}, [])

0

การโปรแกรมเชิงฟังก์ชัน

const fs = require('fs')
const path = require('path')
const R = require('ramda')

const getDirectories = pathName => {
    const isDirectory = pathName => fs.lstatSync(pathName).isDirectory()
    const mapDirectories = pathName => R.map(name => path.join(pathName, name), fs.readdirSync(pathName))
    const filterDirectories = listPaths => R.filter(isDirectory, listPaths)

    return {
        paths:R.pipe(mapDirectories)(pathName),
        pathsFiltered: R.pipe(mapDirectories, filterDirectories)(pathName)
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.