Trabalhar com o sistema de arquivos
Cada loja da Tailwind Traders grava os totais de vendas em um arquivo e envia esse arquivo para uma localização central. Para usar esses arquivos, a empresa precisa criar um processo em lotes que possa funcionar com o sistema de arquivos.
Aqui, você aprende a usar o Node.js para ler o sistema de arquivos a fim de descobrir arquivos e diretórios.
Incluir o módulo fs
O Node.js fornece um módulo interno, fs (abreviação em inglês de sistema de arquivos), para trabalhar com o sistema de arquivos. Como ele faz parte do runtime do Node.js, você não precisa instalá-lo, basta fazer referência a ele da mesma forma que faria com qualquer outra dependência.
O módulo fs tem um namespace promises
que tem versões promise
de todos os métodos. Usar o namespace promise
é a maneira preferida de trabalhar com o módulo fs, pois ele permite que você use async
para evitar a complexidade dos retornos de chamada ou o bloqueio de métodos síncronos.
const fs = require("fs").promises;
Você pode usar o módulo fs para realizar várias operações em arquivos e diretórios. Ele tem vários métodos a serem escolhidos. No momento, vamos nos concentrar apenas no que você precisa saber para trabalhar com diretórios.
Listar o conteúdo em um diretório com fs.readdir
Uma das tarefas que você faz com frequência com o módulo fs é listar ou enumerar o conteúdo em um determinado diretório. Por exemplo, a Tailwind Traders tem uma pasta raiz chamada stores. Nessa pasta estão as subpastas organizadas por número da loja. Dentro dessas pastas está o total de arquivos de vendas. A estrutura é parecida com esta:
📂 stores
📄 sales.json
📄 totals.txt
📂 201
📂 202
Para ler o conteúdo da pasta, você pode usar o método readdir
assíncrono. A maioria das operações no módulo fs tem as opções síncronas (com Sync
no final) e assíncronas. Os resultados são retornados em ordem alfanumérica.
const fs = require("fs").promises;
async function main() {
const items = await fs.readdir("stores");
console.log(items);
}
main();
A lista de itens classificados em ordem alfanumérica tem esta aparência:
[ '201', '202', '203', '204' ]
Determinar o tipo de conteúdo com isDirectory
Ao ler o conteúdo de um diretório, você recebe as pastas e os arquivos como uma matriz de cadeias de caracteres. Você pode determinar quais cadeias de caracteres são os arquivos e quais são os diretórios passando a opção withFileTypes
. Essa opção retorna uma matriz de objetos Dirent
em vez de uma matriz de cadeias de caracteres. O objeto Dirent
tem métodos isFile
e isDirectory
que você pode usar para determinar o tipo de objeto com o qual você está lidando.
const fs = require("fs").promises;
async function main() {
const items = await fs.readdir("stores", { withFileTypes: true });
for (let item of items) {
const type = item.isDirectory() ? "folder" : "file";
console.log(`${item.name}: ${type}`);
}
}
main();
A lista de itens classificados em ordem alfanumérica tem esta aparência:
201: folder
202: folder
203: folder
204: folder
Uma observação sobre recursão
Frequentemente, você pode precisar trabalhar com estruturas de diretório complexas que incluem várias pastas aninhadas, cada uma potencialmente contendo mais subpastas e arquivos. Nesses casos, você precisa de uma maneira de navegar por essa estrutura semelhante a uma árvore para encontrar arquivos específicos.
Para conseguir isso, você pode criar uma função que identifica se um item é uma pasta. Se for, a função irá procurar mais arquivos dentro dessa pasta. Esse processo é repetido para cada pasta encontrada.
Isso é feito usando uma técnica chamada de recursão, na qual a função chama a si mesma para pesquisar dentro das pastas recém-encontradas. Isso permite que o programa "percorra" por toda a árvore de diretórios, acessando cada pasta aninhada até que todas as pastas tenham sido exploradas.
const fs = require("fs").promises;
async function findFiles(folderName) {
let results = []
results.push(`${folderName}`);
const items = await fs.readdir(folderName, { withFileTypes: true });
for (const item of items) {
if (item.isDirectory()) {
// RECURSION - calling the function from within itself
const resultsReturned = await findFiles(`${folderName}/${item.name}`);
results = results.concat(resultsReturned);
} else {
results.push(`${folderName}/${item.name}`);
}
}
return results;
}
findFiles("stores").then((results) => console.log(results));
A saída se parece com isso:
[
'stores',
'stores/201',
'stores/201/sales.json',
'stores/202',
'stores/202/sales.json',
'stores/203',
'stores/203/sales.json',
'stores/204',
'stores/204/sales.json'
]
Usar um ambiente de desenvolvimento predefinido
Este módulo de treinamento oferece um contêiner de desenvolvimento, em um navegador ou em seu computador local. Este contêiner fornece todo o ambiente necessário para que você possa usar este módulo de treinamento sem precisar instalar um IDE ou o Node.js. Você não precisa saber nada sobre o contêiner para concluir este módulo de treinamento.