연습 - 파일 시스템 작업
Tailwind Traders는 전 세계에 많은 오프라인 매장이 있습니다. 매일 밤, 매장에서 전날의 모든 매출 합계를 포함하는 sales.json 파일을 만듭니다. 해당 파일은 매장 ID별로 명명된 폴더에 구성됩니다.
이 연습에서는 폴더에서 sales.json이라는 파일을 검색할 수 있는 Node.js 프로그램을 작성합니다.
개발 컨테이너에서 프로젝트 열기
MicrosoftDocs/node-essentials
GitHub 리포지토리의main
분기에 새 GitHub Codespace를 만드는 프로세스를 시작합니다.codespace 만들기 페이지에서 codespace 구성 설정을 검토한 다음, 새 codespace 만들기를 선택합니다.
codespace가 생성될 때까지 기다립니다. 이 프로세스에는 몇 분 정도 걸릴 수 있습니다.
codespace에서 새 터미널을 엽니다.
Node.js가 사용자 환경에 설치되어 있는지 확인합니다.
node --version
개발 컨테이너는
v20.5.1
과(와) 같은 Node.js LTS 버전을 사용합니다. 정확한 버전은 다를 수 있습니다.이 프로젝트의 나머지 연습은 이 개발 컨테이너의 컨텍스트에서 수행됩니다.
sales.json 파일 찾기
수행할 작업은 stores 폴더에서 모든 파일을 찾는 것입니다.
stores 폴더와 이 폴더 내의 번호가 매겨진 각 하위 폴더를 확장합니다.
fs 모듈 포함
./nodejs-files
하위 폴더에서 index.js 파일을 만들어 편집기에서 엽니다.파일 맨 위에 다음 코드를 추가하여 fs 모듈을 파일에 포함합니다.
const fs = require("fs").promises;
다음으로 코드의
main
진입점인 함수를 만듭니다. 이 파일의 마지막 코드 줄은main
메서드를 호출합니다.const fs = require("fs").promises; async function main() {} main();
비동기 함수를 호출하는 일반적인 CommonJS 상용구 코드입니다.
파일을 찾는 함수 작성 sales.json
folderName
매개 변수를 사용하는findSalesFiles
라는 새 함수를 만듭니다.async function findSalesFiles(folderName) { // FIND SALES FILES }
함수 내에서
findSalesFiles
다음 코드를 추가하여 이러한 작업을 완료합니다.- (1) 프로그램에서 찾은 모든 판매 파일의 경로를 보관하려면 맨 위에 배열을 추가합니다.
- (2) 메서드를 사용하여 currentFolder를 읽습니다
readdir
. - (3) 비동
for...of
기 루프를 사용하여 메서드에서readdir
반환된 각 항목에 대해 루프할 블록을 추가합니다. - (4) 항목이
if
파일인지 디렉터리인지 확인하는 문을 추가합니다. - (5) 항목이 디렉터리 인 경우 재귀적으로 함수
findSalesFiles
를 다시 호출하여 항목에 대한 경로를 전달합니다. - (6) 디렉터리가 아닌 경우 검사 추가하여 항목 이름이 sales.json과 일치하는지 확인합니다.
async function findSalesFiles(folderName) { // (1) Add an array at the top, to hold the paths to all the sales files that the program finds. let results = []; // (2) Read the currentFolder with the `readdir` method. const items = await fs.readdir(folderName, { withFileTypes: true }); // (3) Add a block to loop over each item returned from the `readdir` method using the asynchronous `for...of` loop. for (const item of items) { // (4) Add an `if` statement to determine if the item is a file or a directory. if (item.isDirectory()) { // (5) If the item is a directory, recursively call the function `findSalesFiles` again, passing in the path to the item. const resultsReturned = await findSalesFiles(`${folderName}/${item.name}`); results = results.concat(resultsReturned); } else { // (6) If it's not a directory, add a check to make sure the item name matches *sales.json*. if (item.name === "sales.json") { results.push(`${folderName}/${item.name}`); } } } return results; }
이 새
findSaleFiles
함수를main
메서드에서 호출합니다. 파일을 검색할 위치로 stores 폴더 이름을 전달합니다.async function main() { const results = await findSalesFiles("stores"); console.log(results); }
전체 애플리케이션은 다음과 같습니다.
const fs = require("fs").promises; async function findSalesFiles(folderName) { // (1) Add an array at the top, to hold the paths to all the sales files that the program finds. let results = []; // (2) Read the currentFolder with the `readdir` method. const items = await fs.readdir(folderName, { withFileTypes: true }); // (3) Add a block to loop over each item returned from the `readdir` method using the asynchronous `for...of` loop. for (const item of items) { // (4) Add an `if` statement to determine if the item is a file or a directory. if (item.isDirectory()) { // (5) If the item is a directory, recursively call the function `findSalesFiles` again, passing in the path to the item. const resultsReturned = await findSalesFiles(`${folderName}/${item.name}`); results = results.concat(resultsReturned); } else { // (6) If it's not a directory, add a check to make sure the item name matches *sales.json*. if (item.name === "sales.json") { results.push(`${folderName}/${item.name}`); } } } return results; } async function main() { const results = await findSalesFiles("stores"); console.log(results); } main();
프로그램 실행
터미널에서 다음 명령을 입력하여 프로그램을 실행합니다.
node index.js
프로그램에 다음과 같은 출력이 표시됩니다.
[ 'stores/201/sales.json', 'stores/202/sales.json', 'stores/203/sales.json', 'stores/204/sales.json', ]
아주 좋습니다! 디렉터리를 트래버스하고 디렉터리에 있는 sales.json 파일을 모두 찾는 명령줄 프로그램을 작성했습니다.
그러나 이 예제에서 하위 폴더 경로를 생성한 방법은 문자열을 연결해야 하기 때문에 약간 번거롭습니다. 또한 다른 경로 구분 기호를 사용하는 운영 체제(예: Windows)에서 문제가 발생할 수도 있습니다.
다음 섹션에서는 path 모듈을 사용하여 여러 운영 체제에서 작동하는 경로를 생성하는 방법을 알아봅니다.
처리하기 어려운 부분이 있나요?
이 연습을 수행하는 동안 처리하기 어려운 부분이 있었다면 여기서 완성된 코드를 참조하세요. index.js의 모든 내용을 제거하고 이 솔루션으로 바꿉니다.
const fs = require("fs").promises;
async function findSalesFiles(folderName) {
// (1) Add an array at the top, to hold the paths to all the sales files that the program finds.
let results = [];
// (2) Read the currentFolder with the `readdir` method.
const items = await fs.readdir(folderName, { withFileTypes: true });
// (3) Add a block to loop over each item returned from the `readdir` method using the asynchronous `for...of` loop.
for (const item of items) {
// (4) Add an `if` statement to determine if the item is a file or a directory.
if (item.isDirectory()) {
// (5) If the item is a directory, recursively call the function `findSalesFiles` again, passing in the path to the item.
const resultsReturned = await findSalesFiles(`${folderName}/${item.name}`);
results = results.concat(resultsReturned);
} else {
// (6) If it's not a directory, add a check to make sure the item name matches *sales.json*.
if (item.name === "sales.json") {
results.push(`${folderName}/${item.name}`);
}
}
}
return results;
}
async function main() {
const results = await findSalesFiles("stores");
console.log(results);
}
main();