Exercício – ler e gravar em arquivos

Concluído

Você está quase terminando de criar uma obra-prima do Node.js para Tailwind Traders. Até agora, o seu código lê qualquer pasta, localiza todos os arquivos .json e cria um arquivo totals.txt na pasta salesTotals.

Neste exercício, você conclui o projeto lendo o .json files, adicionando os totais do repositório e gravando o total geral no arquivo salesTotals/totals.txt.

Criar um método para calcular os totais de vendas

  1. Na parte superior de index.js, logo abaixo da instrução require("path"), crie uma função que calcula o total de vendas. Esse método deverá captar a matriz de caminhos de arquivo em que ele pode iterar.

    async function calculateSalesTotal(salesFiles) {
      let salesTotal = 0;
    
      // READ FILES LOOP
    
      return salesTotal;
    }
    
  2. Dentro dessa função, substitua // READ FILES LOOP por um loop que:

    • (1) Itera na matriz salesFiles.
    • (2) Lê o arquivo.
    • (3) Analisa o conteúdo como JSON.
    • (4) Incrementa a variável salesTotal com o valor total do arquivo.
     async function calculateSalesTotal(salesFiles) {
    
       // Final sales total
       let salesTotal = 0;
    
       // (1) Tterates over the `salesFiles` array.
       for (file of salesFiles) {
    
         // (2) Reads the file.
         const fileContents = await fs.readFile(file)
    
         // (3) Parses the content as JSON.
         const data = JSON.parse(fileContents);
    
         // (4) Increments the `salesTotal` variable with the `total` value from the file.
         salesTotal += data.total;
       }
       return salesTotal;
     }
    

Chamar o método calculateSalesTotals

  1. Na função main, modifique o código para:

    • (1) Adicione uma chamada à função calculateSalesTotals logo acima da chamada fs.writeFile.
    • (2) Modifique o bloco fs.writeFile para gravar o valor da variável salesTotal no arquivo totals.txt.
    async function main() {
      const salesDir = path.join(__dirname, "stores");
      const salesTotalsDir = path.join(__dirname, "salesTotals");
    
      try {
        await fs.mkdir(salesTotalsDir);
      } catch {
        console.log(`${salesTotalsDir} already exists.`);
      }
    
      const salesFiles = await findSalesFiles(salesDir);
    
      // (1) Add a call to the `calculateSalesTotals` function just above the `fs.writeFile` call.
      const salesTotal = await calculateSalesTotal(salesFiles);
    
      // (2) Modify the `fs.writeFile` block to write the value of the `salesTotal` variable to the *totals.txt* file.
      await fs.writeFile(
        path.join(salesTotalsDir, "totals.txt"),
        `${salesTotal}\r\n`,
        { flag: "a" }
      );
    }
    

Executar o programa

  1. Execute o programa no terminal.

    node index.js
    
    185933.76
    
  2. Abra o arquivo ./salesTotals/totals.txt para ver o total de todas as vendas dos arquivos sales.json e totals.json: 185933.76.

  3. Execute o programa no terminal novamente.

    node index.js
    
    185933.76
    185933.76
    

    O arquivo totals.txt agora tem uma segunda linha. Toda vez que você executa o programa, os totais são somados novamente e uma nova linha é escrita no arquivo.

Excelente trabalho! Você escreveu uma ferramenta inteligente, robusta e prática que a Tailwind Traders pode usar para processar todas as vendas de lojas todas as noites. Na próxima seção, vamos examinar o que você aprendeu e dar algumas dicas para se lembrar.

Ficou preso?

Se você ficou preso durante este exercício, este é o código completo deste projeto.

const fs = require("fs").promises;
const path = require("path");

async function calculateSalesTotal(salesFiles) {
  
  // Final sales total
  let salesTotal = 0;
  
  // (1) Tterates over the `salesFiles` array.
  for (file of salesFiles) {
    
    // (2) Reads the file.
    const fileContents = await fs.readFile(file)

    // (3) Parses the content as JSON.
    const data = JSON.parse(fileContents);

    // (4) Increments the `salesTotal` variable with the `total` value from the file.
    salesTotal += data.total;
  }
  return salesTotal;
}

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` function 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(path.join(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 (path.extname(item.name) === ".json")
        results.push(`${folderName}/${item.name}`);
    }
  }

  return results;
}

async function main() {
  const salesDir = path.join(__dirname, "stores");
  const salesTotalsDir = path.join(__dirname, "salesTotals");

  // create the salesTotal directory if it doesn't exist
  try {
    await fs.mkdir(salesTotalsDir);
  } catch {
    console.log(`${salesTotalsDir} already exists.`);
  }

  // find paths to all the sales files
  const salesFiles = await findSalesFiles(salesDir);

  // read through each sales file to calculate the sales total
  const salesTotal = await calculateSalesTotal(salesFiles);

  // write the total to the "totals.json" file
  await fs.writeFile(
    path.join(salesTotalsDir, "totals.txt"),
    `${salesTotal}\r\n`,
    { flag: "a" }
  );
  console.log(`Wrote sales totals to ${salesTotalsDir}`);
}

main();

Parabéns! Você fez a leitura dos arquivos, analisou o JSON e gravou o total em um arquivo. Você concluiu o projeto!

Limpar o contêiner de desenvolvimento

Depois de concluir o projeto, limpe o ambiente de desenvolvimento ou devolva-o ao estado padrão.

A exclusão do ambiente GitHub Codespaces garante que você possa maximizar a quantidade de horas gratuitas por núcleo que você tem direito na sua conta.

Importante

Para saber mais sobre os direitos da sua conta do GitHub, confira O GitHub Codespaces inclui mensalmente armazenamento e horas de núcleo.

  1. Entre no painel do GitHub Codespaces (https://github.com/codespaces).

  2. Localize os codespaces atualmente em execução provenientes do repositório GitHub MicrosoftDocs/node-essentials.

    Screenshot of all the running codespaces including their status and templates.

  3. Abra o menu de contexto do codespace e selecione Excluir.

    Screenshot of the context menu for a single codespace with the delete option highlighted.