디렉터리 nodejs 내의 모든 디렉터리 가져오기
저는 이것이 간단한 일이기를 바랐지만, 저는 그렇게 할 수 있는 어떤 것도 찾을 수 없습니다.
지정된 폴더/디렉토리 내의 모든 폴더/디렉토리를 가져오려고 합니다.
예를 들어 다음과 같습니다.
<MyFolder>
|- SomeFolder
|- SomeOtherFolder
|- SomeFile.txt
|- SomeOtherFile.txt
|- x-directory
다음과 같은 이점이 있을 것으로 예상됩니다.
["SomeFolder", "SomeOtherFolder", "x-directory"]
위의 경로가 그런 식으로 제공되었다면...
위와 같은 작업을 수행할 수 있는 것이 이미 존재합니까?
약속.
import { readdir } from 'fs/promises'
const getDirectories = async source =>
(await readdir(source, { withFileTypes: true }))
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name)
콜백
import { readdir } from 'fs'
const getDirectories = (source, callback) =>
readdir(source, { withFileTypes: true }, (err, files) => {
if (err) {
callback(err)
} else {
callback(
files
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name)
)
}
})
싱크로너스
import { readdirSync } from 'fs'
const getDirectories = source =>
readdirSync(source, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name)
경로를 사용하여 디렉터리를 나열합니다.
function getDirectories(path) {
return fs.readdirSync(path).filter(function (file) {
return fs.statSync(path+'/'+file).isDirectory();
});
}
재귀해
저는 모든 하위 디렉터리와 모든 하위 디렉터리 등을 가져올 방법을 찾아 여기에 왔습니다.인정된 답변을 바탕으로 저는 다음과 같이 썼습니다.
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))];
}
이렇게 하면 됩니다.
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
커피스크립트(비동기화)
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}));
}
}
});
}
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));``
라이브러리를 수에는 를 사용할 수 .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
고지 사항:제가 작가입니다.
node.js 버전 >= v10.13.0의 경우 fs.readdirSync는 fs 배열을 반환합니다.다른 객체의 경우withFileTypes
옵션이 다음으로 설정됨true
.
그래서 당신이 사용할 수 있습니다.
const fs = require('fs')
const directories = source => fs.readdirSync(source, {
withFileTypes: true
}).reduce((a, c) => {
c.isDirectory() && a.push(c.name)
return a
}, [])
비동기 호출을 약속하는 fs-extra 및 새 대기 비동기 구문 사용:
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("/")
이 답변은 다음과 같은 차단 기능을 사용하지 않습니다.readdirSync
또는statSync
외부 의존성을 사용하지 않으며 콜백 지옥의 깊은 곳에서 자신을 찾지 않습니다.
대신에 우리는 약속과 같은 현대적인 자바스크립트 편의를 사용합니다.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
위에 사용된 모듈은 유사한 문제를 해결하기 위해 설계된 함수 집합에서 추출된 패턴이었습니다.자세한 내용은 이와 관련된 Q&A를 참조하십시오.
또한 비동기 버전의 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);
});
}
ES6가 포함된 완전 비동기 버전으로 네이티브 패키지, fs.promise 및 async/wait만 파일 작업을 병렬로 수행합니다.
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);
}
테스트 완료, 작동이 양호합니다.
graph-fs를 사용할 수 있습니다.
const {Node} = require("graph-fs");
const directory = new Node("/path/to/directory");
const subDirectories = directory.children.filter(child => child.is.directory);
이 답변의 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
판본이런 거 있으면 돼요.
디렉터리 길이를 기록하고 모든 비동기 상태 작업이 완료되었는지 여부를 나타내는 표시기로 사용합니다.
비동기 상태 작업이 완료되면 모든 파일 상태가 확인되었으므로 콜백을 호출합니다.
Node.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);
});
});
use fs、path 모듈이 폴더를 가져올 수 있습니다.Promise를 사용합니다.를 채울 경우 디렉토리()를 isFile() Nodejs--fs--fs로 변경할 수 있습니다.Stats.마지막으로 Nodejs---Path에서 파일 'name file'extname 등을 가져올 수 있습니다.
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);
});
});
글로벌 패키지를 사용하여 디렉터리만 찾으려면 슬래시를 추가하십시오.
import {promise as glob} from "glob-promise"
const firstLevelFolders = await glob("MyFolder/*/")
const recursiveFolders = await glob("MyFolder/**/")
다른 누군가가 웹 검색에서 여기까지 와서 이미 종속성 목록에 그룬트를 가지고 있는 경우, 이에 대한 대답은 사소한 것이 됩니다.제 솔루션은 다음과 같습니다.
/**
* 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);
}
또 다른 재귀적 접근법
마유르가 나를 알게 해준 것에 감사합니다.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)
}
}, [])
함수형 프로그래밍
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)
}
}
모듈을 사용하는 것이 합리적이라면 dree를 사용할 수 있습니다.
const dree = require('dree');
const options = {
depth: 1
};
const fileCallback = function() {};
const directories = [];
const dirCallback = function(dir) {
directories.push(dir.name);
};
dree.scan('./dir', {});
console.log(directories);
지정된 경로(./dir")의 하위 디렉터리가 인쇄됩니다.
옵션을 지정하지 않은 경우depth: 1
지정된 경로의 지시된 하위 디렉터리뿐만 아니라 모든 디렉터리를 재귀적인 방식으로 가져올 수도 있습니다.
언급URL : https://stackoverflow.com/questions/18112204/get-all-directories-within-directory-nodejs
'programing' 카테고리의 다른 글
다른 사용자의 저장소에서 원격 분기를 가져오는 방법 (0) | 2023.05.27 |
---|---|
MongoDB 2.4의 Meteor 앱에서 전체 텍스트 검색 구현 (0) | 2023.05.27 |
MongoDB: 컬렉션에 있는 수십억 개의 문서 (0) | 2023.05.27 |
공백이 아닌 변경사항만 추가 (0) | 2023.05.27 |
getopts를 사용하여 긴 명령줄 및 짧은 명령줄 옵션 처리 (0) | 2023.05.27 |