Получить все каталоги в каталоге nodejs
Я надеялся, что это будет простая вещь, но я не могу найти ничего там, чтобы сделать это.
Я просто хочу получить все папки/каталоги в данной папке / каталоге.
например:
<MyFolder>
|- SomeFolder
|- SomeOtherFolder
|- SomeFile.txt
|- SomeOtherFile.txt
|- x-directory
Я ожидал бы получить массив:
["SomeFolder", "SomeOtherFolder", "x-directory"]
или выше с пути, если он был подан...
Итак, что-нибудь уже существует, чтобы сделать выше?
14 ответов:
вот более короткая, синхронная версия ответ это может перечислить все каталоги (скрытые или нет) в текущем каталоге:
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)
благодаря синтаксическим функциям JavaScript ES6 (ES2015) это один лайнер:
синхронных версия
const { readdirSync, statSync } = require('fs') const { join } = require('path') const dirs = p => readdirSync(p).filter(f => statSync(join(p, f)).isDirectory())асинхронная версия для узла.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 }
список каталогов, использующих путь.
function getDirectories(path) { return fs.readdirSync(path).filter(function (file) { return fs.statSync(path+'/'+file).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 (асинхронный)
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 (асинхронный)
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})); } } }); }
рекурсивное решение
Я пришел сюда в поисках пути, чтобы получить все поддиректории, и все их подкаталоги и т. д. Здание на принято отвечать, я написал Вот это:
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))]; }
кроме того, если вы можете использовать внешние библиотеки, вы можете использовать
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
отказ от ответственности: я автор.
и асинхронная версия getDirectories, вам нужно асинхронный модуль для этого:
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); }); }
используя fs-extra, который обещает асинхронные вызовы fs, и новый синтаксис await 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("/")
Я бы лично объявил функцию 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 жалуется в противном случае, и вы можете создавать новый вызов функции на каждом проходе цикла.
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версия. Вы можете иметь что-то вроде этого.
запишите длину каталога, использует его в качестве индикатора, чтобы сказать, если все асинхронные задачи stat закончены.
Если асинхронные задачи stat завершены, все файлы stat были проверены, поэтому вызовите обратный вызов
Это будет работать только как узел.js-это один поток, потому что он предполагает, что никакие две асинхронные задачи не увеличат счетчик в то же время.
'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); } }); }); });как вы можете видеть, это" глубина первый "подход, и это может привести к обратному вызову ад, и это не совсем" функционально". Люди пытаются решить эту проблему с помощью Promise, обернув асинхронную задачу в объект 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 модуль может получить папку. это использование обещают. Если вы получите заполнение, вы можете изменить isDirectory() до isFile() Nodejs--fs--FS. Stats. наконец, вы можете получить имя файла 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); }); });
на всякий случай, если кто-то еще попадает сюда из веб-поиска и уже хрюкает в своем списке зависимостей, ответ на это становится тривиальным. Вот мое решение:
/** * 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 function getFolders(path) { let result = Array(); let files = await fs.readdir(path); for (let i = 0; i < files.length; i++) { var filePath = path + '/' + file; if (await fs.stat(filePath).isDirectory()) { result.push(filePath); } } return result; }Я также рекомендую использовать fs-extra вместо fs..
Comments