Oefening: met het bestandssysteem werken

Voltooid

Tailwind Traders beschikt over de hele wereld over veel fysieke winkels. Elke avond maken deze winkels een bestand met de naam sales.json. Dit bestand bevat het totaal voor al hun verkopen van de afgelopen dag. Deze bestanden zijn ingedeeld in mappen met de naam winkel-id.

In deze oefening schrijft u een Node.js-programma dat kan zoeken naar bestanden met de naam sales.json in een map.

Project openen in ontwikkelingscontainer

  1. Start het proces om een nieuwe GitHub Codespace te maken op de main vertakking van de MicrosoftDocs/node-essentials GitHub-opslagplaats.

  2. Controleer op de pagina Codespace maken de configuratie-instellingen voor codespace en selecteer vervolgens Nieuwe codespace maken

    Screenshot of the confirmation screen before creating a new codespace.

  3. Wacht tot de coderuimte is gestart. Dit opstartproces kan enkele minuten duren.

  4. Open een nieuwe terminal in de codespace.

    Tip

    U kunt het hoofdmenu gebruiken om naar de menuoptie Terminal te navigeren en vervolgens de optie Nieuwe terminal te selecteren.

    Screenshot of the codespaces menu option to open a new terminal.

  5. Controleer of Node.js is geïnstalleerd in uw omgeving:

    node --version
    

    De dev-container maakt gebruik van een Node.js LTS-versie, zoals v20.5.1. De exacte versie kan afwijken.

  6. De resterende oefeningen in dit project vinden plaats in de context van deze ontwikkelingscontainer.

De sales.json-bestanden zoeken

Uw taak is om alle bestanden in de map Winkels te vinden.

Vouw de stores-map en alle genummerde mappen in die map uit.

Screenshot that shows the project folder structure.

De fs-module opnemen

  1. Maak in de ./nodejs-files submap een index.js-bestand om het te openen in de editor.

  2. Voeg boven aan het bestand de volgende code toe om de fs-module in het bestand op te nemen.

    const fs = require("fs").promises;
    
  3. Maak vervolgens de main functie die het toegangspunt voor uw code is. Met de laatste coderegel in dit bestand wordt de main methode aangeroepen.

    const fs = require("fs").promises;
    
    async function main() {}
    
    main();
    

    Dit is typische CommonJS-standaardcode om een asynchrone functie aan te roepen.

Een functie schrijven om de sales.json bestanden te vinden

  1. Maak een nieuwe functie met de naam findSalesFiles waarbij een folderName-parameter wordt gebruikt.

    async function findSalesFiles(folderName) {
      // FIND SALES FILES
    }
    
  2. Voeg in de findSalesFiles functie de volgende code toe om deze taken uit te voeren:

    • (1) Voeg bovenaan een matrix toe om de paden op te slaan naar alle verkoopbestanden die door het programma worden gevonden.
    • (2) Lees de currentFolder met de readdir methode.
    • (3) Voeg een blok toe om elk item te herhalen dat wordt geretourneerd door de readdir methode met behulp van de asynchrone lus for...of .
    • (4) Voeg een if instructie toe om te bepalen of het item een bestand of map is.
    • (5) Als het item een map is, roept u de functie findSalesFiles recursief opnieuw aan, waarbij u het pad naar het item doorgeeft.
    • (6) Als het geen map is, voegt u een controle toe om te controleren of de itemnaam overeenkomt met 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;
    }
    
  3. Roep deze nieuwe findSaleFiles-functie aan via de methode main. Geef de stores-mapnaam door als de locatie voor het zoeken naar bestanden.

     async function main() {
       const results = await findSalesFiles("stores");
       console.log(results);
     }
    
  4. De volledige toepassing ziet er als volgt uit:

    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();
    

Het programma uitvoeren

  1. Voer de volgende opdracht in de terminal in om het programma uit te voeren.

    node index.js
    
  2. Als het goed is, ziet u de volgende uitvoer.

    [
     'stores/201/sales.json',
     'stores/202/sales.json',
     'stores/203/sales.json',
     'stores/204/sales.json',
    ]
    

Uitstekend. U hebt een opdrachtregelprogramma geschreven dat elke map kan doorlopen en alle sales.json-bestanden erin kan vinden.

De manier waarop het pad naar submappen in dit voorbeeld is opgebouwd, is echter nogal onhandig omdat hiervoor tekenreeksen moeten worden samengevoegd. Bovendien bestaat de kans op problemen in andere besturingssystemen (zoals Windows) waarvoor andere scheidingstekens voor paden worden gebruikt.

In de volgende sectie leert u meer over het opbouwen van paden die voor alle besturingssystemen werken, met behulp van de path-module.

Vastgelopen?

Als u op een bepaald punt in deze oefening niet meer verder kunt, vindt u hier de voltooide code. Verwijder alles in index.js en vervang dit door deze oplossing.

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();