Exercício – trabalhar com o sistema de arquivos

Concluído

A Tailwind Traders tem muitas lojas físicas em todo o mundo. A cada noite, essas lojas criam um arquivo chamado sales.json, que contém o total para todas as vendas dela do dia anterior. Esses arquivos são organizados em pastas nomeadas por ID de loja.

Neste exercício, você escreve um programa Node.js que pode pesquisar arquivos chamados sales.json em uma determinada pasta.

Abrir projeto no contêiner de desenvolvimento

  1. Inicie o processo para criar um GitHub Codespace no branch main do repositório GitHub MicrosoftDocs/node-essentials.

  2. Na página Criar codespace , analise as definições de configuração do codespace e selecione Criar novo codespace

    Screenshot of the confirmation screen before creating a new codespace.

  3. Aguarde até que o codespace seja iniciado. Esse processo de inicialização pode levar alguns minutos.

  4. Abra um novo terminal no codespace.

    Dica

    Você pode usar o menu principal para navegar até a opção de menu Terminal e, em seguida, selecionar a opção Novo Terminal.

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

  5. Valide se o .NET 7 está instalado em seu ambiente:

    node --version
    

    O contêiner de desenvolvimento usa uma versão Node.js LTS, como v20.5.1. A versão exata pode ser diferente.

  6. Os exercícios restantes neste projeto ocorrem no contexto desse contêiner de desenvolvimento.

Localizar os arquivos sales.json

Sua tarefa é localizar todos os arquivos na pasta stores .

Expanda a pasta stores e cada uma das pastas numeradas dentro dela.

Screenshot that shows the project folder structure.

Incluir o módulo fs

  1. Na subpasta ./nodejs-files, crie um arquivo index.js para abri-lo no editor.

  2. Na parte superior do arquivo, adicione o código a seguir para incluir o módulo fs no arquivo.

    const fs = require("fs").promises;
    
  3. Em seguida, crie a função main, que é o ponto de entrada para o seu código. A última linha de código nesse arquivo invoca o método main.

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

    Esse é um código clichê CommonJS típico para chamar uma função assíncrona.

Escrever uma função para localizar os arquivos sales.json

  1. Crie uma função chamada findSalesFiles que usa um parâmetro folderName.

    async function findSalesFiles(folderName) {
      // FIND SALES FILES
    }
    
  2. Dentro da função findSalesFiles, adicione o seguinte código para concluir estas tarefas:

    • (1) Adicione uma matriz na parte superior para manter os caminhos para todos os arquivos de vendas que o programa encontrar.
    • (2) Leia o currentFolder com o método readdir.
    • (3) Adicione um bloco para fazer loop sobre cada item retornado do método readdir usando o loop assíncrono for...of.
    • (4) Adicione uma instrução if para determinar se o item é um arquivo ou um diretório.
    • (5) Se o item for um diretório, chame recursivamente a funçãofindSalesFiles novamente, passando o caminho para o item.
    • (6) Se não for um diretório, adicione uma verificação para verificar se o nome do item corresponde a 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. Chame essa nova função findSaleFiles do método main. Passe o nome da pasta stores como o local para pesquisar arquivos.

     async function main() {
       const results = await findSalesFiles("stores");
       console.log(results);
     }
    
  4. O aplicativo completo tem a seguinte aparência:

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

Executar o programa

  1. Insira o comando a seguir no terminal para executar o programa.

    node index.js
    
  2. O programa deve mostrar a saída a seguir.

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

Excelente! Você escreveu com êxito um programa de linha de comando que atravessa qualquer diretório e encontra todos os arquivos sales.json dentro dele.

No entanto, a maneira como o caminho para as subpastas foi construído nesse exemplo é um pouco complicada porque requer a concatenação de cadeias de caracteres. Além disso, você pode encontrar problemas em outros sistemas operacionais (como o Windows) que usam separadores de caminhos diferentes.

Na próxima seção, você aprenderá a construir caminhos que funcionam em vários sistemas operacionais usando o módulo path.

Ficou preso?

Se você ficou preso em algum ponto deste exercício, veja o código concluído. Remova tudo em index.js e substitua por essa solução.

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