Exercise - Work with the file system
You can use Node.js to find and return information about files and folders.
Tailwind Traders has many physical stores all over the world. Each night, these stores create a file called sales.json that contains the total for all their sales for the previous day. These files are organized in folders by store ID.
In this exercise, you'll write a Node.js program that can search for files called sales.json in a folder.
Sign in to the sandbox
Activate the Microsoft Learn sandbox by selecting Activate Sandbox at the top of this page.
Set up the environment
Run the following command in Azure Cloud Shell on the right to ensure that you're working with the most current version of Node.js:
source <(curl -Ls https://aka.ms/install-node-lts)
Clone the project
Run the following command to clone the example project for this module:
git clone https://github.com/MicrosoftDocs/node-essentials && cd node-essentials/nodejs-filesOpen the Cloud Shell editor by running the following command in Cloud Shell.
code .Expand the stores folder and each of the numbered folders inside.
Find the sales.json files
You need to find all the files in only the topmost location: the stores folder.
Include the fs module
Select the index.js file to open it in the editor.
Include the fs module at the top of the file.
const fs = require("fs").promises;Create a
mainmethod. This method will be the entry point for your code. The last line of code in this file will invoke themainmethod.const fs = require("fs").promises; async function main() {} main();
Write a method to find the sales.json files
Create a new method called
findSalesFilesthat takes afolderNameparameter.async function findSalesFiles(folderName) { // FIND SALES FILES }Add an array at the top, which will hold the paths to all the sales files that the program finds.
async function findSalesFiles(folderName) { // this array will hold sales files as they are found let salesFiles = []; // FIND SALES FILES }Create a method within this function called
findFiles, which also takes afolderNameparameter.async function findSalesFiles(folderName) { // this array will hold sales files as they are found let salesFiles = []; async function findFiles(folderName) { // FIND SALES FILES } }This new method
findFilesis created inside the mainfindSalesMethodmethod so that it can run as many times as necessary to find all the sales files and populate thesalesFilesarray. ThefolderNamevalue is the path to the current folder.Inside the
findFilesmethod, read thecurrentFolderpath with thereaddirsyncmethod.async function findSalesFiles(folderName) { // this array will hold sales files as they are found let salesFiles = []; async function findFiles(folderName) { // read all the items in the current folder const items = await fs.readdir(folderName, { withFileTypes: true }); // FIND SALES FILES } }Add a block to loop over each item returned from the
readdirsyncmethod.async function findSalesFiles(folderName) { // this array will hold sales files as they are found let salesFiles = []; async function findFiles(folderName) { // read all the items in the current folder const items = await fs.readdir(folderName, { withFileTypes: true }); // iterate over each found item for (item of items) { // FIND SALES FILES } } }Add an
ifstatement to determine if the item is a file or a directory.async function findSalesFiles(folderName) { // this array will hold sales files as they are found let salesFiles = []; async function findFiles(folderName) { // read all the items in the current folder const items = await fs.readdir(folderName, { withFileTypes: true }); // iterate over each found item for (item of items) { if (item.isDirectory()) { // FIND SALES FILES IN THIS FOLDER } else { // FIND SALES FILES } } } }If the item is a directory, call the
findFilesmethod again, passing in the path to the item. If it's not, add a check to make sure the item name matches sales.json.async function findSalesFiles(folderName) { // this array will hold sales files as they are found let salesFiles = []; async function findFiles(folderName) { // read all the items in the current folder const items = await fs.readdir(folderName, { withFileTypes: true }); // iterate over each found item for (item of items) { if (item.isDirectory()) { // search this directory for files (this is recursion!) await findFiles(`${folderName}/${item.name}`); } else { // Make sure the discovered file is a sales.json file if (item.name === "sales.json") { // store the file path in the salesFiles array salesFiles.push(`${folderName}/${item.name}`); } } } } await findFiles(folderName); return salesFiles; }Call this new
findSaleFilesfunction from themainmethod. Pass in the stores folder name as the location to search for files.async function main() { const salesFiles = await findSalesFiles("stores"); console.log(salesFiles); }Press Ctrl-S to save the file, and press Ctrl-Q to close the editor.
Run the program
Enter the following command into Cloud Shell to run the program.
node index.jsThe program should show the following output.
[ 'stores/201/sales.json', 'stores/202/sales.json', 'stores/203/sales.json', 'stores/204/sales.json', ]
Excellent! You've successfully written a command-line program that will traverse any directory and find all the sales.json files inside.
However, the way that the path to subfolders was constructed in this example is a little clumsy because it requires concatenating strings together. Also, you might run into issues on other operating systems (like Windows) that use different path separators.
In the next section, you'll learn how to construct paths that work across operating systems by using the path module.
Got stuck?
If you got stuck at any point in this exercise, here's the completed code. Remove everything in index.js and replace it with this solution.
const fs = require("fs");
async function findSalesFiles(folderName) {
// this array will hold sales files as they are found
let salesFiles = [];
async function findFiles(folderName) {
// read all the items in the current folder
const items = await fs.readdirSync(folderName, { withFileTypes: true });
// iterate over each found item
for (item of items) {
// if the item is a directory, it will need to be searched for files
if (item.isDirectory()) {
// search this directory for files (this is recursion!)
await findFiles(`${folderName}/${item.name}`);
} else {
// Make sure the discovered file is a sales.json file
if (item.name === "sales.json") {
// store the file path in the salesFiles array
salesFiles.push(`${folderName}/${item.name}`);
}
}
}
}
// find the sales files
await findFiles(folderName);
// return the array of found file paths
return salesFiles;
}
async function main() {
const salesFiles = await findSalesFiles("stores");
console.log(salesFiles);
}
main();
Trebate pomoć? Pogledajte naš vodič za rješavanje problema ili pošaljite željene povratne informacije prijavljivanjem problema.