Ferramenta de Inspeção de Diretórios
Deslize para mostrar o menu
Este capítulo apresenta um desafio: criar um aplicativo de console avançado chamado DirInspect Pro. Este aplicativo permitirá que você analise detalhadamente qualquer diretório e obtenha estatísticas relevantes sobre seus arquivos e subdiretórios.
Desafio
Imagine um cenário em que você precisa navegar por um labirinto de pastas contendo arquivos e dados essenciais. O DirInspect Pro é seu aliado nessa jornada, fornecendo uma visão abrangente da estrutura e do conteúdo do diretório.
O Aplicativo Resultante
Prepare-se para utilizar os recursos do DirInspect Pro. O aplicativo fornecerá informações essenciais, como:
- O número total de itens;
- O tamanho agregado de todos os itens;
- O nome e o tamanho do maior arquivo;
- A lista detalhada dos nomes e tamanhos de cada arquivo individualmente.
Dois Caminhos para Escolher
Você tem dois caminhos à frente.
- O primeiro é enfrentar esse desafio diretamente, aprimorando suas habilidades sem orientação;
- O segundo é seguir um guia útil que garante seu sucesso.
Independentemente do caminho escolhido, você terá uma jornada recompensadora que culmina na criação de um aplicativo de console envolvente e funcional.
Plano Mestre
- Etapa 1: Importar módulos necessários;
- Etapa 2: Definir a função getStats;
- Etapa 3: Definir a função analyzeFile;
- Etapa 4: Definir a função analyzeDirectory;
- Etapa 5: Definir e invocar a função main;
- Conclusão;
- Código completo do aplicativo.
Etapa 1: Importar módulos necessários
Para iniciar esta jornada, é preciso ter as ferramentas certas. Comece importando dois módulos principais: fs.promises para gerenciar o sistema de arquivos de forma assíncrona e path para manipular caminhos de arquivos de maneira eficiente.
const fs = require("fs").promises;
const path = require("path");
- Linha 1: importa o módulo nativo
fs. A propriedade.promisesfornece acesso à API baseada em promessas, permitindo operações assíncronas de arquivos utilizandoasync/await; - Linha 2: importa o módulo nativo
path. Este módulo oferece utilitários para trabalhar com caminhos de arquivos e diretórios, incluindo manipulação e normalização de caminhos.
Etapa 2: Definir a função getStats
A função assíncrona getStats recebe um caminho de arquivo ou diretório como argumento e tenta obter suas estatísticas usando fs.stat.
- Se for bem-sucedida, retorna as estatísticas;
- Se ocorrer um erro, registra uma mensagem de erro e retorna
null.
async function getStats(filePath) {
try {
const stats = await fs.stat(filePath);
return stats;
} catch (err) {
console.error("Error getting stats:", err.message);
return null;
}
}
- Linha 1: declara uma função assíncrona chamada
getStatsque aceita um parâmetrofilePath; - Linhas 2, 5: cria um bloco
try...catchutilizado para tratamento de erros durante a operação assíncrona; - Linha 3: utiliza
await fs.stat(filePath)para obter informações sobre o arquivo especificado, como seu tamanho, data de criação e outros metadados; - Linha 4: retorna o objeto
statsse a operaçãofs.stat()for concluída com sucesso; - Linha 6: registra uma mensagem de erro no console usando
console.error()caso a operação falhe; - Linha 7: retorna
nullpara indicar que as estatísticas do arquivo não puderam ser obtidas.
Etapa 3: Definir a função analyzeFile
A função analyzeFile utiliza a função getStats para obter estatísticas de um arquivo. Se as estatísticas estiverem disponíveis (diferente de null), retorna um objeto contendo o nome do arquivo (extraído usando path.basename) e seu tamanho.
async function analyzeFile(filePath) {
const stats = await getStats(filePath);
if (!stats) return null;
return {
name: path.basename(filePath),
size: stats.size,
};
}
- Linha 1: declara uma função assíncrona chamada
analyzeFileque recebe um parâmetrofilePath; - Linha 2: utiliza
await getStats(filePath)para obter as estatísticas do arquivo para o caminho fornecido; - Linha 3: verifica se
statsé falso. Se as estatísticas não puderem ser obtidas, a função retornanull; - Linhas 5-8: cria e retorna um objeto contendo o nome e o tamanho do arquivo. O nome do arquivo é extraído usando
path.basename(filePath), enquanto o tamanho é obtido destats.size.
Etapa 4: Definir a função analyzeDirectory
A função analyzeDirectory examina um diretório e reúne estatísticas completas sobre seu conteúdo.
Como funciona: ela lê todos os itens dentro do diretório usando fs.readdir. Para cada item:
- Constrói o caminho completo com
path.join; - Usa
getStatspara detectar se é um arquivo ou uma pasta; - Se for um arquivo:
- Chama
analyzeFilepara obter{ name, size }; - Atualiza totais, maior arquivo e a lista de arquivos.
- Chama
- Se for um diretório:
- Chama recursivamente
analyzeDirectory; - Mescla os resultados nas estatísticas atuais.
- Chama recursivamente
async function analyzeDirectory(directoryPath) {
let totalItems = 0;
let totalFiles = 0;
let totalSize = 0;
let largestFile = { name: "", size: 0 };
let fileList = [];
try {
const items = await fs.readdir(directoryPath);
for (const item of items) {
const itemPath = path.join(directoryPath, item);
const stats = await getStats(itemPath);
if (!stats) continue;
totalItems++;
if (stats.isFile()) {
const fileInfo = await analyzeFile(itemPath);
if (!fileInfo) continue;
totalFiles++;
totalSize += fileInfo.size;
if (fileInfo.size > largestFile.size) {
largestFile = fileInfo;
}
fileList.push(fileInfo);
} else if (stats.isDirectory()) {
const subDirectoryStats = await analyzeDirectory(itemPath);
totalItems += subDirectoryStats.totalItems;
totalFiles += subDirectoryStats.totalFiles;
totalSize += subDirectoryStats.totalSize;
if (subDirectoryStats.largestFile.size > largestFile.size) {
largestFile = subDirectoryStats.largestFile;
}
fileList = fileList.concat(subDirectoryStats.fileList);
}
}
return {
totalItems,
totalFiles,
totalSize,
largestFile,
fileList
};
} catch (err) {
console.error("Error analyzing directory contents:", err.message);
return {
totalItems: 0,
totalFiles: 0,
totalSize: 0,
largestFile: { name: "", size: 0 },
fileList: []
};
}
}
-
Linha 1: declara uma função assíncrona chamada
analyzeDirectoryque recebe um parâmetrodirectoryPath; -
Linhas 2-6: inicializa variáveis usadas para armazenar estatísticas do diretório, incluindo total de itens, total de arquivos, tamanho total, o maior arquivo e uma lista de arquivos analisados;
-
Linha 8: inicia um bloco
trypara tratar possíveis erros do sistema de arquivos; -
Linha 9: lê o conteúdo do diretório usando
fs.readdir()e armazena o resultado no arrayitems; -
Linha 11: inicia um loop
for...ofpara iterar por cada item no diretório; -
Linha 12: cria o caminho completo para o item atual usando
path.join(); -
Linha 13: obtém as estatísticas para o item atual usando
getStats(); -
Linha 14: ignora o item atual se as estatísticas não puderem ser obtidas;
-
Linha 16: incrementa
totalItemspara cada arquivo ou diretório processado com sucesso; -
Linhas 18-29: tratam o processamento de arquivos:
-
Linha 19: chama
analyzeFile()para obter o nome e o tamanho do arquivo; -
Linha 20: ignora o arquivo se a análise falhar;
- Linhas 22-23: atualiza o total de arquivos e o tamanho acumulado dos arquivos;
- Linhas 25-27: atualiza
largestFilese o arquivo atual for maior que o anteriormente registrado;
-
Linha 29: adiciona as informações do arquivo à
fileList; -
Linhas 30-42: tratam o processamento de diretórios:
-
Linha 31: chama recursivamente
analyzeDirectory()para o subdiretório;- Linhas 33-35: mescla as estatísticas do subdiretório nos totais atuais;
- Linhas 37-39: atualiza
largestFilese o subdiretório contiver um arquivo maior;
-
Linha 41: mescla as listas de arquivos usando
concat(); -
Linhas 45-50: retornam um objeto contendo as estatísticas finais do diretório;
-
Linhas 52-62: tratam erros registrando uma mensagem e retornando um objeto de estatísticas padrão.
Passo 5: Definir a Função main e Invocar
A função main é o ponto de entrada do script. Ela especifica o caminho do diretório a ser analisado (neste caso, ./docs), chama a função analyzeDirectory para obter as estatísticas do diretório e de seu conteúdo, e então exibe as informações coletadas.
A função imprime:
- O número total de itens;
- O número total de arquivos;
- O tamanho total;
- Os detalhes sobre o maior arquivo;
- A lista de arquivos no diretório.
async function main() {
const directoryPath = "./docs";
const directoryStats = await analyzeDirectory(directoryPath);
console.log("Directory Analysis:");
console.log("Total items:", directoryStats.totalItems);
console.log("Total files:", directoryStats.totalFiles);
console.log("Total size (bytes):", directoryStats.totalSize);
console.log(
"Largest file:",
directoryStats.largestFile.name,
"Size:",
directoryStats.largestFile.size,
"bytes"
);
console.log("\nFile List:");
for (const file of directoryStats.fileList) {
console.log(file.name, "Size:", file.size, "bytes");
}
}
main();
-
Linha 1: declara uma função assíncrona chamada
main; -
Linha 2: define a variável
directoryPath, que armazena o caminho do diretório que será analisado; -
Linha 3: chama
analyzeDirectory()com odirectoryPathespecificado e armazena o resultado na variáveldirectoryStatsusandoawait; -
Linhas 5-17: exibem as estatísticas calculadas do diretório usando
console.log(), incluindo o número total de itens, total de arquivos, tamanho total e informações sobre o maior arquivo; -
Linhas 18-20: percorrem o array
fileListarmazenado emdirectoryStats; -
exibem o nome e o tamanho de cada arquivo no diretório;
-
Linha 23: chama a função
main()para iniciar o processo de análise.
Código Completo do Aplicativo
const fs = require("fs").promises;
const path = require("path");
async function getStats(filePath) {
try {
const stats = await fs.stat(filePath);
return stats;
} catch (err) {
console.error("Error getting stats:", err.message);
return null;
}
}
async function analyzeFile(filePath) {
const stats = await getStats(filePath);
if (!stats) return null;
return {
name: path.basename(filePath),
size: stats.size
};
}
async function analyzeDirectory(directoryPath) {
let totalItems = 0;
let totalFiles = 0;
let totalSize = 0;
let largestFile = { name: "", size: 0 };
let fileList = [];
try {
const items = await fs.readdir(directoryPath);
for (const item of items) {
const itemPath = path.join(directoryPath, item);
const stats = await getStats(itemPath);
if (!stats) continue;
totalItems++;
if (stats.isFile()) {
const fileInfo = await analyzeFile(itemPath);
if (!fileInfo) continue;
totalFiles++;
totalSize += fileInfo.size;
if (fileInfo.size > largestFile.size) {
largestFile = fileInfo;
}
fileList.push(fileInfo);
} else if (stats.isDirectory()) {
const subDirectoryStats = await analyzeDirectory(itemPath);
totalItems += subDirectoryStats.totalItems;
totalFiles += subDirectoryStats.totalFiles;
totalSize += subDirectoryStats.totalSize;
if (subDirectoryStats.largestFile.size > largestFile.size) {
largestFile = subDirectoryStats.largestFile;
}
fileList = fileList.concat(subDirectoryStats.fileList);
}
}
return {
totalItems,
totalFiles,
totalSize,
largestFile,
fileList
};
} catch (err) {
console.error("Error analyzing directory contents:", err.message);
return {
totalItems: 0,
totalFiles: 0,
totalSize: 0,
largestFile: { name: "", size: 0 },
fileList: []
};
}
}
async function main() {
const directoryPath = "./docs";
const directoryStats = await analyzeDirectory(directoryPath);
console.log("Directory Analysis:");
console.log("Total items:", directoryStats.totalItems);
console.log("Total files:", directoryStats.totalFiles);
console.log("Total size (bytes):", directoryStats.totalSize);
console.log(
"Largest file:",
directoryStats.largestFile.name,
"Size:",
directoryStats.largestFile.size,
"bytes"
);
console.log("\nFile List:");
for (const file of directoryStats.fileList) {
console.log(file.name, "Size:", file.size, "bytes");
}
}
main();
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo