Node.jsfs.readdir 재귀 디렉터리 검색
fs.readdir를 사용한 비동기 디렉토리 검색에 대한 아이디어가 있습니까?재귀를 소개하고 읽기 디렉터리 함수를 다음 디렉터리와 함께 호출할 수 있다는 것을 알고 있습니다. 하지만 비동기식이 아닌 것이 조금 걱정됩니다.
아이디어 있어요?노드워크는 훌륭하지만 readdir처럼 배열에 있는 파일만 제공하지는 않습니다.비록 ~일지라도
다음과 같은 출력을 찾고 있습니다.
['file1.txt', 'file2.txt', 'dir/file3.txt']
이를 달성하는 데는 기본적으로 두 가지 방법이 있습니다.비동기 환경에서는 직렬 및 병렬의 두 가지 루프가 있음을 알 수 있습니다.직렬 루프는 다음 반복으로 이동하기 전에 하나의 반복이 완료될 때까지 기다립니다. 이렇게 하면 루프의 모든 반복이 순서대로 완료됩니다.병렬 루프에서는 모든 반복이 동시에 시작되고 하나가 다른 반복보다 먼저 완료될 수 있지만 직렬 루프보다 훨씬 빠릅니다.따라서 이 경우에는 워크가 완료되고 결과가 반환되는 한 워크가 어떤 순서로 완료되는지는 중요하지 않으므로 병렬 루프를 사용하는 것이 좋습니다.
병렬 루프는 다음과 같습니다.
var fs = require('fs');
var path = require('path');
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var pending = list.length;
if (!pending) return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending) done(null, results);
});
} else {
results.push(file);
if (!--pending) done(null, results);
}
});
});
});
};
직렬 루프는 다음과 같습니다.
var fs = require('fs');
var path = require('path');
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err) return done(err);
var i = 0;
(function next() {
var file = list[i++];
if (!file) return done(null, results);
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
next();
});
} else {
results.push(file);
next();
}
});
})();
});
};
홈 디렉토리에서 테스트하려면 다음을 수행합니다(경고: 홈 디렉토리에 많은 항목이 있는 경우 결과 목록이 커집니다.
walk(process.env.HOME, function(err, results) {
if (err) throw err;
console.log(results);
});
편집: 개선된 예제입니다.
이 기능은 약속, 활용/약속, 파괴, 비동기 대기, 맵+축소 등 노드 8에서 사용할 수 있는 최신 유행어 기능을 최대한 사용하여 동료들이 무슨 일이 일어나고 있는지 파악하려고 할 때 머리를 긁적이게 합니다.
노드 8+
외부 종속성이 없습니다.
const { promisify } = require('util');
const { resolve } = require('path');
const fs = require('fs');
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
async function getFiles(dir) {
const subdirs = await readdir(dir);
const files = await Promise.all(subdirs.map(async (subdir) => {
const res = resolve(dir, subdir);
return (await stat(res)).isDirectory() ? getFiles(res) : res;
}));
return files.reduce((a, f) => a.concat(f), []);
}
사용.
getFiles(__dirname)
.then(files => console.log(files))
.catch(e => console.error(e));
노드 10.10+
노드 10+에 대해 더 많은 Whizbang으로 업데이트됨:
const { resolve } = require('path');
const { readdir } = require('fs').promises;
async function getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(dirents.map((dirent) => {
const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
}));
return Array.prototype.concat(...files);
}
11부터는 "11.15.0"을 할 수 .files.flat()에 Array.prototype.concat(...files)파일 배열을 평평하게 만듭니다.
노드 11+
만약 당신이 모든 사람의 머리를 완전히 날려버리고 싶다면, 당신은 비동기기를 사용하여 다음 버전을 사용할 수 있습니다.소비자는 정말 멋진 기능을 제공할 뿐만 아니라 한 번에 한 번씩 결과를 가져올 수 있기 때문에 대규모 디렉토리에 더 적합합니다.
const { resolve } = require('path');
const { readdir } = require('fs').promises;
async function* getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
const res = resolve(dir, dirent.name);
if (dirent.isDirectory()) {
yield* getFiles(res);
} else {
yield res;
}
}
}
반환 유형이 이제 약속이 아닌 비동기식이기 때문에 사용량이 변경되었습니다.
;(async () => {
for await (const f of getFiles('.')) {
console.log(f);
}
})()
누군가가 관심을 가질 경우를 대비하여, 저는 여기에 동기화 장치에 대해 더 많이 썼습니다: https://qwtel.com/posts/software/async-generators-in-the-wild/
누군가 유용하다고 생각할 경우를 대비해서, 저도 동기식 버전을 만들었습니다.
var walk = function(dir) {
var results = [];
var list = fs.readdirSync(dir);
list.forEach(function(file) {
file = dir + '/' + file;
var stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
/* Recurse into a subdirectory */
results = results.concat(walk(file));
} else {
/* Is a file */
results.push(file);
}
});
return results;
}
팁: 필터링할 때 리소스를 적게 사용합니다.이 함수 자체 내에서 필터링합니다.예: 바꾸기results.push(file);이하의 부호로필요에 따라 조정합니다.
file_type = file.split(".").pop();
file_name = file.split(/(\\|\/)/g).pop();
if (file_type == "json") results.push(file);
A. 파일 모듈을 확인합니다.워크라는 기능이 있습니다.
file.walk(시작, 콜백)
파일 트리를 탐색하여 각 디렉터리에 대한 콜백을 호출하고 전달합니다(null, dirPath, dirs, files).
이것은 당신을 위한 것일지도 모릅니다!네, 비동기식입니다.하지만 필요하다면 전체 경로를 집계해야 할 것 같습니다.
B. 대안이자 내가 가장 좋아하는 것 중 하나: unix를 사용합니다.find그것 때문에이미 프로그래밍된 것을 왜 다시 합니까?꼭 필요한 것은 아니지만 확인해 볼 가치가 있습니다.
var execFile = require('child_process').execFile;
execFile('find', [ 'somepath/' ], function(err, stdout, stderr) {
var file_list = stdout.split('\n');
/* now you've got a list with full path file names */
});
Find에는 몇 개의 폴더만 변경된 경우 후속 검색을 매우 빠르게 수행하는 훌륭한 내장 캐싱 메커니즘이 있습니다.
이 작업을 수행하려면 node-glob을 사용하는 것이 좋습니다.
var glob = require( 'glob' );
glob( 'dirname/**/*.js', function( err, files ) {
console.log( files );
});
또 다른 좋은 npm 패키지는 glob입니다.
npm install glob
그것은 매우 강력하며 당신의 모든 재귀적인 요구를 충족시켜야 합니다.
편집:
저는 사실 glob에 대해 완벽하게 만족하지 못했기 때문에 readdirp를 만들었습니다.
저는 API를 통해 파일과 디렉터리를 재귀적으로 찾고 특정 필터를 적용하는 것이 매우 쉽다고 확신합니다.
다음을 통해 해당 설명서를 읽어보고 기능에 대한 자세한 내용을 확인하고 설치하십시오.
npm install readdirp
짧고 현대적이며 효율적인 솔루션:
import {readdir} from 'node:fs/promises'
import {join} from 'node:path'
const walk = async (dirPath) => Promise.all(
await readdir(dirPath, { withFileTypes: true }).then((entries) => entries.map((entry) => {
const childPath = join(dirPath, entry.name)
return entry.isDirectory() ? walk(childPath) : childPath
})),
)
힌트를 준 기능에 대한 특별한 감사:{withFileTypes: true}.
이렇게 하면 원하는 원본 디렉토리의 트리 구조가 자동으로 유지됩니다.예를 들어 다음과 같은 경우:
const allFiles = await walk('src')
그리고나서allFiles다음과 같은 트리가 될 수 있습니다.
[
[
'src/client/api.js',
'src/client/http-constants.js',
'src/client/index.html',
'src/client/index.js',
[ 'src/client/res/favicon.ico' ],
'src/client/storage.js'
],
[ 'src/crypto/keygen.js' ],
'src/discover.js',
[
'src/mutations/createNewMutation.js',
'src/mutations/newAccount.js',
'src/mutations/transferCredit.js',
'src/mutations/updateApp.js'
],
[
'src/server/authentication.js',
'src/server/handlers.js',
'src/server/quick-response.js',
'src/server/server.js',
'src/server/static-resources.js'
],
[ 'src/util/prompt.js', 'src/util/safeWriteFile.js' ],
'src/util.js'
]
그러나 트리 구조를 원하지 않는 경우 쉽게 평평하게 만들 수 있습니다.
allFiles.flat(Number.POSITIVE_INFINITY)
[
'src/client/api.js',
'src/client/http-constants.js',
'src/client/index.html',
'src/client/index.js',
'src/client/res/favicon.ico',
'src/client/storage.js',
'src/crypto/keygen.js',
'src/discover.js',
'src/mutations/createNewMutation.js',
'src/mutations/newAccount.js',
'src/mutations/transferCredit.js',
'src/mutations/updateApp.js',
'src/server/authentication.js',
'src/server/handlers.js',
'src/server/quick-response.js',
'src/server/server.js',
'src/server/static-resources.js',
'src/util/prompt.js',
'src/util/safeWriteFile.js',
'src/util.js'
]
만약 당신이 npm 패키지를 사용하고 싶다면, 렌치가 꽤 좋습니다.
var wrench = require("wrench");
var files = wrench.readdirSyncRecursive("directory");
wrench.readdirRecursive("directory", function (error, files) {
// live your dreams
});
EDIT(2018):
최근에 읽은 사람:작성자는 2015년에 이 패키지를 더 이상 사용하지 않았습니다.
rench.js는 더 이상 사용되지 않으며 꽤 오랫동안 업데이트되지 않았습니다.추가 파일 시스템 작업을 수행하려면 fs-extra를 사용하는 것이 좋습니다.
비동기
const fs = require('fs')
const path = require('path')
const readdir = (p, done, a = [], i = 0) => fs.readdir(p, (e, d = []) =>
d.map(f => readdir(a[a.push(path.join(p, f)) - 1], () =>
++i == d.length && done(a), a)).length || done(a))
readdir(__dirname, console.log)
동기화
const fs = require('fs')
const path = require('path')
const readdirSync = (p, a = []) => {
if (fs.statSync(p).isDirectory())
fs.readdirSync(p).map(f => readdirSync(a[a.push(path.join(p, f)) - 1], a))
return a
}
console.log(readdirSync(__dirname))
비동기식 읽기
function readdir (currentPath, done, allFiles = [], i = 0) {
fs.readdir(currentPath, function (e, directoryFiles = []) {
if (!directoryFiles.length)
return done(allFiles)
directoryFiles.map(function (file) {
var joinedPath = path.join(currentPath, file)
allFiles.push(joinedPath)
readdir(joinedPath, function () {
i = i + 1
if (i == directoryFiles.length)
done(allFiles)}
, allFiles)
})
})
}
readdir(__dirname, console.log)
참고: 두 버전 모두 심볼릭 링크를 따릅니다(원본과 동일).fs.readdir)
재귀 포함
var fs = require('fs')
var path = process.cwd()
var files = []
var getFiles = function(path, files){
fs.readdirSync(path).forEach(function(file){
var subpath = path + '/' + file;
if(fs.lstatSync(subpath).isDirectory()){
getFiles(subpath, files);
} else {
files.push(path + '/' + file);
}
});
}
부르기
getFiles(path, files)
console.log(files) // will log all files in directory
저는 위의 chjj의 답변을 좋아했고 그 시작이 없었다면 제 버전의 병렬 루프를 만들 수 없었을 것입니다.
var fs = require("fs");
var tree = function(dir, done) {
var results = {
"path": dir
,"children": []
};
fs.readdir(dir, function(err, list) {
if (err) { return done(err); }
var pending = list.length;
if (!pending) { return done(null, results); }
list.forEach(function(file) {
fs.stat(dir + '/' + file, function(err, stat) {
if (stat && stat.isDirectory()) {
tree(dir + '/' + file, function(err, res) {
results.children.push(res);
if (!--pending){ done(null, results); }
});
} else {
results.children.push({"path": dir + "/" + file});
if (!--pending) { done(null, results); }
}
});
});
});
};
module.exports = tree;
Gist도 만들었습니다.댓글 환영합니다.나는 여전히 노드에서 시작하고 있습니다.JS 영역이기 때문에 그것이 제가 더 배우고 싶은 한 방법 중 하나입니다.
node-dir를 사용하여 원하는 출력을 정확하게 생성합니다.
var dir = require('node-dir');
dir.files(__dirname, function(err, files) {
if (err) throw err;
console.log(files);
//we have an array of files now, so now we can iterate that array
files.forEach(function(path) {
action(null, path);
})
});
다음은 간단한 동기식 재귀 솔루션입니다.
const fs = require('fs')
const getFiles = path => {
const files = []
for (const file of fs.readdirSync(path)) {
const fullPath = path + '/' + file
if(fs.lstatSync(fullPath).isDirectory())
getFiles(fullPath).forEach(x => files.push(file + '/' + x))
else files.push(file)
}
return files
}
용도:
const files = getFiles(process.cwd())
console.log(files)
비동기식으로 작성할 수는 있지만 그럴 필요는 없습니다.입력 디렉토리가 존재하고 액세스할 수 있는지 확인합니다.
현대 약속 기반 읽기 디어 재귀 버전:
const fs = require('fs');
const path = require('path');
const readDirRecursive = async (filePath) => {
const dir = await fs.promises.readdir(filePath);
const files = await Promise.all(dir.map(async relativePath => {
const absolutePath = path.join(filePath, relativePath);
const stat = await fs.promises.lstat(absolutePath);
return stat.isDirectory() ? readDirRecursive(absolutePath) : absolutePath;
}));
return files.flat();
}
TypeScript에서 qwtel의 응답 변형
import { resolve } from 'path';
import { readdir } from 'fs/promises';
async function* getFiles(dir: string): AsyncGenerator<string> {
const entries = await readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const res = resolve(dir, entry.name);
if (entry.isDirectory()) {
yield* getFiles(res);
} else {
yield res;
}
}
}
바닐라 ES6 + 비동기/대기 + 작고 읽을 수 있는
저는 이 스레드에서 제가 찾고 있던 답을 찾지 못했습니다. 서로 다른 답에 비슷한 요소가 몇 개 있었지만, 저는 단순하고 읽을 수 있는 것을 원했습니다.
미래의 누군가에게 도움이 될 경우(예: 몇 달 후의 나 자신), 제가 사용하게 된 것은 다음과 같습니다.
const { readdir } = require('fs/promises');
const { join } = require('path');
const readdirRecursive = async dir => {
const files = await readdir( dir, { withFileTypes: true } );
const paths = files.map( async file => {
const path = join( dir, file.name );
if ( file.isDirectory() ) return await readdirRecursive( path );
return path;
} );
return ( await Promise.all( paths ) ).flat( Infinity );
}
module.exports = {
readdirRecursive,
}
저는 최근에 이것을 코딩했고, 이것을 여기서 공유하는 것이 말이 될 것이라고 생각했습니다.코드는 비동기 라이브러리를 사용합니다.
var fs = require('fs');
var async = require('async');
var scan = function(dir, suffix, callback) {
fs.readdir(dir, function(err, files) {
var returnFiles = [];
async.each(files, function(file, next) {
var filePath = dir + '/' + file;
fs.stat(filePath, function(err, stat) {
if (err) {
return next(err);
}
if (stat.isDirectory()) {
scan(filePath, suffix, function(err, results) {
if (err) {
return next(err);
}
returnFiles = returnFiles.concat(results);
next();
})
}
else if (stat.isFile()) {
if (file.indexOf(suffix, file.length - suffix.length) !== -1) {
returnFiles.push(filePath);
}
next();
}
});
}, function(err) {
callback(err, returnFiles);
});
});
};
다음과 같이 사용할 수 있습니다.
scan('/some/dir', '.ext', function(err, files) {
// Do something with files that ends in '.ext'.
console.log(files);
});
파일하운드라는 라이브러리도 옵션입니다.지정된 디렉토리(기본적으로 작업 디렉토리)를 재귀적으로 검색합니다.다양한 필터, 콜백, 약속 및 동기화 검색을 지원합니다.
예를 들어 현재 작업 디렉터리에서 모든 파일을 검색합니다(콜백 사용).
const Filehound = require('filehound');
Filehound.create()
.find((err, files) => {
if (err) {
return console.error(`error: ${err}`);
}
console.log(files); // array of files
});
또는 특정 디렉토리를 약속하고 지정합니다.
const Filehound = require('filehound');
Filehound.create()
.paths("/tmp")
.find()
.each(console.log);
추가 사용 사례 및 사용 예는 문서를 참조하십시오. https://github.com/nspragg/filehound
고지 사항:제가 작가입니다.
비동기/대기를 사용하면 다음과 같이 작동합니다.
const FS = require('fs');
const readDir = promisify(FS.readdir);
const fileStat = promisify(FS.stat);
async function getFiles(dir) {
let files = await readDir(dir);
let result = files.map(file => {
let path = Path.join(dir,file);
return fileStat(path).then(stat => stat.isDirectory() ? getFiles(path) : path);
});
return flatten(await Promise.all(result));
}
function flatten(arr) {
return Array.prototype.concat(...arr);
}
/**
* Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument.
*
* @param {Function} nodeFunction
* @returns {Function}
*/
module.exports = function promisify(nodeFunction) {
return function(...args) {
return new Promise((resolve, reject) => {
nodeFunction.call(this, ...args, (err, data) => {
if(err) {
reject(err);
} else {
resolve(data);
}
})
});
};
};
Node 8+에는 Promise가 내장되어 있습니다.
더 빠른 결과를 제공할 수 있는 제너레이터 접근 방식에 대한 다른 답변을 참조하십시오.
단순한 비동기 약속 기반
const fs = require('fs/promises');
const getDirRecursive = async (dir) => {
try {
const items = await fs.readdir(dir);
let files = [];
for (const item of items) {
if ((await fs.lstat(`${dir}/${item}`)).isDirectory()) files = [...files, ...(await getDirRecursive(`${dir}/${item}`))];
else files.push({file: item, path: `${dir}/${item}`, parents: dir.split("/")});
}
return files;
} catch (e) {
return e
}
};
용도:await getDirRecursive("./public");
final-fs 라이브러리를 확인하십시오.다음을 제공합니다.readdirRecursive함수:
ffs.readdirRecursive(dirPath, true, 'my/initial/path')
.then(function (files) {
// in the `files` variable you've got all the files
})
.otherwise(function (err) {
// something went wrong
});
독립 실행형 약속 이행
이 예에서는 when.js promise 라이브러리를 사용하고 있습니다.
var fs = require('fs')
, path = require('path')
, when = require('when')
, nodefn = require('when/node/function');
function walk (directory, includeDir) {
var results = [];
return when.map(nodefn.call(fs.readdir, directory), function(file) {
file = path.join(directory, file);
return nodefn.call(fs.stat, file).then(function(stat) {
if (stat.isFile()) { return results.push(file); }
if (includeDir) { results.push(file + path.sep); }
return walk(file, includeDir).then(function(filesInDir) {
results = results.concat(filesInDir);
});
});
}).then(function() {
return results;
});
};
walk(__dirname).then(function(files) {
console.log(files);
}).otherwise(function(error) {
console.error(error.stack || error);
});
옵션매변수포함습니다했를개를 했습니다.includeDir가 포함됩니다. 파일 에 " 파목록디포함다됩니가"로 디렉토리가 됩니다.true.
klaw와 klaw-sync는 이런 종류의 것을 고려할 가치가 있습니다.이것들은 node-fs-extra의 일부였습니다.
Node 10.3+의 경우 대기 솔루션은 다음과 같습니다.
#!/usr/bin/env node
const FS = require('fs');
const Util = require('util');
const readDir = Util.promisify(FS.readdir);
const Path = require('path');
async function* readDirR(path) {
const entries = await readDir(path,{withFileTypes:true});
for(let entry of entries) {
const fullPath = Path.join(path,entry.name);
if(entry.isDirectory()) {
yield* readDirR(fullPath);
} else {
yield fullPath;
}
}
}
async function main() {
const start = process.hrtime.bigint();
for await(const file of readDirR('/mnt/home/media/Unsorted')) {
console.log(file);
}
console.log((process.hrtime.bigint()-start)/1000000n);
}
main().catch(err => {
console.error(err);
});
이 솔루션의 이점은 결과 처리를 즉시 시작할 수 있다는 것입니다. 예를 들어 미디어 디렉터리에 있는 모든 파일을 읽는 데 12초가 걸리지만 이렇게 하면 몇 밀리초 안에 첫 번째 결과를 얻을 수 있습니다.
여기 또 다른 구현이 있습니다.위의 솔루션에는 제한이 없으므로 디렉터리 구조가 크면 모두 스래시되고 리소스가 부족하게 됩니다.
var async = require('async');
var fs = require('fs');
var resolve = require('path').resolve;
var scan = function(path, concurrency, callback) {
var list = [];
var walker = async.queue(function(path, callback) {
fs.stat(path, function(err, stats) {
if (err) {
return callback(err);
} else {
if (stats.isDirectory()) {
fs.readdir(path, function(err, files) {
if (err) {
callback(err);
} else {
for (var i = 0; i < files.length; i++) {
walker.push(resolve(path, files[i]));
}
callback();
}
});
} else {
list.push(path);
callback();
}
}
});
}, concurrency);
walker.push(path);
walker.drain = function() {
callback(list);
}
};
50개의 동시성을 사용하는 것이 매우 효과적이며, 작은 디렉토리 구조에 대한 간단한 구현만큼 빠릅니다.
recursive-readdir 모듈에는 이 기능이 있습니다.
블루버드와 함께 일하기 위해 트레버 시니어의 약속 기반 답변을 수정했습니다.
var fs = require('fs'),
path = require('path'),
Promise = require('bluebird');
var readdirAsync = Promise.promisify(fs.readdir);
var statAsync = Promise.promisify(fs.stat);
function walkFiles (directory) {
var results = [];
return readdirAsync(directory).map(function(file) {
file = path.join(directory, file);
return statAsync(file).then(function(stat) {
if (stat.isFile()) {
return results.push(file);
}
return walkFiles(file).then(function(filesInDir) {
results = results.concat(filesInDir);
});
});
}).then(function() {
return results;
});
}
//use
walkDir(__dirname).then(function(files) {
console.log(files);
}).catch(function(e) {
console.error(e); {
});
재미를 위해 highland.js streams 라이브러리에서 작동하는 흐름 기반 버전이 있습니다.그것은 빅터 부에 의해 공저되었습니다.
###
directory >---m------> dirFilesStream >---------o----> out
| |
| |
+--------< returnPipe <-----------+
legend: (m)erge (o)bserve
+ directory has the initial file
+ dirListStream does a directory listing
+ out prints out the full path of the file
+ returnPipe runs stat and filters on directories
###
_ = require('highland')
fs = require('fs')
fsPath = require('path')
directory = _(['someDirectory'])
mergePoint = _()
dirFilesStream = mergePoint.merge().flatMap((parentPath) ->
_.wrapCallback(fs.readdir)(parentPath).sequence().map (path) ->
fsPath.join parentPath, path
)
out = dirFilesStream
# Create the return pipe
returnPipe = dirFilesStream.observe().flatFilter((path) ->
_.wrapCallback(fs.stat)(path).map (v) ->
v.isDirectory()
)
# Connect up the merge point now that we have all of our streams.
mergePoint.write directory
mergePoint.write returnPipe
mergePoint.end()
# Release backpressure. This will print files as they are discovered
out.each H.log
# Another way would be to queue them all up and then print them all out at once.
# out.toArray((files)-> console.log(files))
약속(Q)을 사용하여 기능 스타일로 문제 해결:
var fs = require('fs'),
fsPath = require('path'),
Q = require('q');
var walk = function (dir) {
return Q.ninvoke(fs, 'readdir', dir).then(function (files) {
return Q.all(files.map(function (file) {
file = fsPath.join(dir, file);
return Q.ninvoke(fs, 'lstat', file).then(function (stat) {
if (stat.isDirectory()) {
return walk(file);
} else {
return [file];
}
});
}));
}).then(function (files) {
return files.reduce(function (pre, cur) {
return pre.concat(cur);
});
});
};
배열의 약속을 반환하므로 다음과 같이 사용할 수 있습니다.
walk('/home/mypath').then(function (files) { console.log(files); });
Promise 기반 샌더 라이브러리를 목록에 추가해야 합니다.
var sander = require('sander');
sander.lsr(directory).then( filenames => { console.log(filenames) } );
언급URL : https://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
'programing' 카테고리의 다른 글
| 안드로이드 애플리케이션에서 충돌 데이터를 가져오려면 어떻게 해야 합니까? (0) | 2023.06.01 |
|---|---|
| 스토어를 여는 데 사용된 모델이 스토어를 만드는 데 사용된 모델과 호환되지 않습니다. (0) | 2023.06.01 |
| HTML 페이지에서 스크롤 막대 숨기기 (0) | 2023.06.01 |
| getApplication() vs. getApplicationContext() (0) | 2023.06.01 |
| Jest를 사용하여 단일 파일을 테스트하려면 어떻게 해야 합니까? (0) | 2023.06.01 |