Exercício – trabalhar com o sistema de arquivos
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
Inicie o processo para criar um GitHub Codespace no branch
main
do repositório GitHubMicrosoftDocs/node-essentials
.Na página Criar codespace , analise as definições de configuração do codespace e selecione Criar novo codespace
Aguarde até que o codespace seja iniciado. Esse processo de inicialização pode levar alguns minutos.
Abra um novo terminal no codespace.
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.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.
Incluir o módulo fs
Na subpasta
./nodejs-files
, crie um arquivo index.js para abri-lo no editor.Na parte superior do arquivo, adicione o código a seguir para incluir o módulo fs no arquivo.
const fs = require("fs").promises;
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étodomain
.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
Crie uma função chamada
findSalesFiles
que usa um parâmetrofolderName
.async function findSalesFiles(folderName) { // FIND SALES FILES }
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íncronofor...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ção
findSalesFiles
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; }
Chame essa nova função
findSaleFiles
do métodomain
. Passe o nome da pasta stores como o local para pesquisar arquivos.async function main() { const results = await findSalesFiles("stores"); console.log(results); }
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
Insira o comando a seguir no terminal para executar o programa.
node index.js
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();