Skip to content

Commit 1a7165c

Browse files
committed
4.3
1 parent acf008b commit 1a7165c

File tree

3 files changed

+83
-1
lines changed

3 files changed

+83
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
string, number

04-asynchronous-control-flow-patterns-with-callbacks/listNestedFiles.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { promisify } from 'util';
88
*
99
* ### => 나는, 객체로 트리구조 표현해서 콜백에 전달하도록 했다.
1010
* @param {string} dir
11-
* @param {*} cb
11+
* @param {(err, dirObj?) => any} cb
1212
* @returns {void}
1313
*/
1414
function listNestedFiles(dir, cb) {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { TaskQueue } from "./11-web-spider-v4/TaskQueue.js";
2+
import { readdir, readFile } from 'fs';
3+
4+
/**
5+
* ### 주어진 디렉터리에서 주어진 키워드를 포함하는 모든 텍스트파일을 찾는 함수
6+
* - 모든 검색 완료 후 매칭되는 파일 리스트를 콜백을 사용하여 리턴.
7+
* - 매칭되는 파일이 없으면 빈 배열을 리턴.
8+
* - 재귀적으로 검색하기.
9+
* - 디렉터리 및 파일검색, 키워드 검색을 병렬적으로 수행하기.
10+
* - 제어 가능한 병렬 작업의 수를 유지하기.
11+
*
12+
* ### 검색 로직은 listNestedFiles 를 기반으로 약간 수정/추가 해서 만들고 동시성 제어는 예제 TeskQueue를 이용.
13+
*
14+
* @param {string} dir 로컬 파일시스템의 디렉터리 경로
15+
* @param {string} keyword 텍스트 파일 내에서 찾을 키워드
16+
* @param {(err, files) => any} cb
17+
*/
18+
function recursiveFind(dir, keyword, cb) {
19+
20+
const fileList = [];
21+
22+
const workQueue = new TaskQueue(500);
23+
workQueue.on('error', cb);
24+
workQueue.on('empty', () => cb(null, fileList));
25+
26+
const next = (nextDir, nextCb) => {
27+
readdir(nextDir, {withFileTypes: true}, (err, files) => {
28+
if (err) {
29+
return nextCb(err);
30+
};
31+
32+
const findTxtFileIncludingKeyword = (fileName, taskCb) => {
33+
readFile(`${nextDir}/${fileName}`, 'utf8', (err, fileContent) => {
34+
if (err) {
35+
return taskCb(err);
36+
};
37+
if (fileContent.includes(keyword)) {
38+
fileList.push(`${nextDir}/${fileName}`);
39+
};
40+
taskCb();
41+
});
42+
};
43+
44+
files
45+
.map(f => { // txt 파일 대상 검색
46+
if (f.isFile() && f.name.endsWith('.txt')) {
47+
workQueue.pushTask(findTxtFileIncludingKeyword.bind(null, f.name));
48+
}
49+
return f;
50+
})
51+
.filter(f => f.isDirectory())
52+
.map(f => f.name)
53+
.filter(f => f.charAt(0) !== '.') // 숨김폴더 제외
54+
.forEach(f => {
55+
workQueue.pushTask((taskCb) => {
56+
next(`${nextDir}/${f}`, taskCb);
57+
});
58+
});
59+
60+
nextCb();
61+
});
62+
};
63+
64+
workQueue.pushTask((taskCb) => {
65+
next(dir, taskCb);
66+
});
67+
68+
}
69+
70+
71+
72+
// --------------------------------------------------------------------------------
73+
74+
75+
76+
recursiveFind('../../', 'number', (err, files) => {
77+
if (err) {
78+
return console.error(err);
79+
};
80+
console.log(files);
81+
});

0 commit comments

Comments
 (0)