Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Verktyg för Kataloginspektion | Bygga Konsolapplikationer med Node.js
Backendutveckling med Node.js och Express.js

Verktyg för Kataloginspektion

Svep för att visa menyn

Detta kapitel presenterar en utmaning: att skapa en avancerad konsolapplikation vid namn DirInspect Pro. Denna app ger dig möjlighet att noggrant analysera valfri katalog och få insiktsfull statistik om dess filer och underkataloger.

Utmaning

Föreställ dig ett scenario där du måste navigera genom en labyrint av mappar som innehåller viktiga filer och data. DirInspect Pro är din följeslagare på denna resa och ger dig omfattande insikter om katalogens struktur och innehåll.

Den färdiga applikationen

Förbered dig på att använda DirInspect Pros funktioner. Applikationen ger dig viktig information, såsom

  • Det totala antalet objekt;
  • Den sammanlagda storleken på alla objekt;
  • Namnet och storleken på den största filen;
  • En detaljerad lista över individuella filnamn och storlekar.

Två vägar att välja

Du har två vägar framför dig.

  • Den första är att anta denna utmaning direkt och finslipa dina färdigheter utan vägledning;
  • Den andra är att följa en hjälpsam guide som garanterar din framgång.

Oavsett vilken väg du väljer väntar en givande resa som kulminerar i skapandet av en fängslande och funktionell konsolapplikation.

Masterplan

  • Steg 1: Importera nödvändiga moduler;
  • Steg 2: Definiera getStats-funktionen;
  • Steg 3: Definiera analyzeFile-funktionen;
  • Steg 4: Definiera analyzeDirectory-funktionen;
  • Steg 5: Definiera och anropa main-funktionen;
  • Slutsats;
  • Komplett applikationskod.

Steg 1: Importera nödvändiga moduler

För att påbörja detta äventyr behöver du rätt verktyg. Börja med att importera två viktiga moduler: fs.promises för att hantera filsystemet asynkront och path för att effektivt hantera filsökvägar.

const fs = require("fs").promises;
const path = require("path");
Kodbeskrivning
expand arrow
  • Rad 1: importerar den inbyggda modulen fs. Egenskapen .promises ger tillgång till API:et baserat på promises, vilket möjliggör asynkrona filoperationer med async/await;
  • Rad 2: importerar den inbyggda modulen path. Denna modul tillhandahåller verktyg för att arbeta med fil- och katalogvägar, inklusive hantering och normalisering av sökvägar.

Steg 2: Definiera getStats-funktionen

Den asynkrona funktionen getStats tar en fil- eller katalogsökväg som argument och försöker hämta dess statistik med hjälp av fs.stat.

  • Om det lyckas returneras statistiken;
  • Om ett fel uppstår loggas ett felmeddelande och null returneras.
async function getStats(filePath) {
  try {
    const stats = await fs.stat(filePath);
    return stats;
  } catch (err) {
    console.error("Error getting stats:", err.message);
    return null;
  }
}
Kodbeskrivning
expand arrow
  • Rad 1: deklarerar en asynkron funktion med namnet getStats som tar emot en parameter filePath;
  • Rad 2, 5: skapar ett try...catch-block som används för felhantering under den asynkrona operationen;
  • Rad 3: använder await fs.stat(filePath) för att hämta information om den angivna filen, såsom dess storlek, skapelsedatum och annan metadata;
  • Rad 4: returnerar objektet stats om operationen fs.stat() lyckas;
  • Rad 6: loggar ett felmeddelande till konsolen med console.error() om operationen misslyckas;
  • Rad 7: returnerar null för att indikera att filstatistiken inte kunde hämtas.

Steg 3: Definiera analyzeFile-funktionen

Funktionen analyzeFile använder funktionen getStats för att hämta statistik för en fil. Om statistik finns tillgänglig (inte null), returneras ett objekt som innehåller filens namn (extraherat med path.basename) och dess storlek.

async function analyzeFile(filePath) {
  const stats = await getStats(filePath);
  if (!stats) return null;

  return {
    name: path.basename(filePath),
    size: stats.size,
  };
}
Kodbeskrivning
expand arrow
  • Rad 1: deklarerar en asynkron funktion med namnet analyzeFile som tar emot en parameter filePath;
  • Rad 2: använder await getStats(filePath) för att hämta filstatistik för den angivna sökvägen;
  • Rad 3: kontrollerar om stats är falskt. Om statistiken inte kunde hämtas returnerar funktionen null;
  • Rader 5-8: skapar och returnerar ett objekt som innehåller filnamn och filstorlek. Filnamnet extraheras med path.basename(filePath), medan storleken hämtas från stats.size.

Steg 4: Definiera funktionen analyzeDirectory

Funktionen analyzeDirectory skannar en katalog och samlar in fullständig statistik om dess innehåll. Så här fungerar det: den läser alla objekt i katalogen med fs.readdir. För varje objekt:

  • Bygger den fullständig sökväg med path.join;
  • Använder getStats för att avgöra om det är en fil eller en mapp;
  • Om det är en fil:
    • Anropar analyzeFile för att få { name, size };
    • Uppdaterar totaler, största filen och fillistan.
  • Om det är en katalog:
    • Anropar rekursivt analyzeDirectory;
    • Slår samman resultaten med den aktuella statistiken.
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: []
    };
  }
}
Kodbeskrivning
expand arrow
  • Rad 1: deklarerar en asynkron funktion med namnet analyzeDirectory som tar emot en parameter directoryPath;

  • Rader 2-6: initierar variabler som används för att lagra katalogstatistik, inklusive totalt antal objekt, totalt antal filer, total storlek, största filen och en lista över analyserade filer;

  • Rad 8: startar ett try-block för att hantera potentiella filsystemfel;

  • Rad 9: läser innehållet i katalogen med fs.readdir() och lagrar resultatet i arrayen items;

  • Rad 11: startar en for...of-loop för att iterera genom varje objekt i katalogen;

  • Rad 12: skapar den fullständiga sökvägen för det aktuella objektet med path.join();

  • Rad 13: hämtar statistik för det aktuella objektet med getStats();

  • Rad 14: hoppar över det aktuella objektet om dess statistik inte kunde hämtas;

  • Rad 16: ökar totalItems för varje fil eller katalog som behandlas framgångsrikt;

  • Rader 18-29: hanterar filbehandling:

  • Rad 19: anropar analyzeFile() för att hämta filnamn och storlek;

  • Rad 20: hoppar över filen om analysen misslyckas;

    • Rader 22-23: uppdaterar det totala antalet filer och ackumulerad filstorlek;
    • Rader 25-27: uppdaterar largestFile om den aktuella filen är större än den tidigare registrerade;
  • Rad 29: lägger till filinformationen i fileList;

  • Rader 30-42: hanterar katalogbehandling:

  • Rad 31: anropar rekursivt analyzeDirectory() för underkatalogen;

    • Rader 33-35: slår samman underkatalogens statistik med de aktuella totalerna;
    • Rader 37-39: uppdaterar largestFile om underkatalogen innehåller en större fil;
  • Rad 41: slår samman fillistor med concat();

  • Rader 45-50: returnerar ett objekt som innehåller den slutliga katalogstatistiken;

  • Rader 52-62: hanterar fel genom att logga ett meddelande och returnera ett standardstatistikobjekt.

Steg 5: Definiera main-funktionen och anropa

Funktionen main är skriptets startpunkt. Den anger sökvägen till katalogen som ska analyseras (i detta fall ./docs), anropar funktionen analyzeDirectory för att hämta statistik om katalogen och dess innehåll, och skriver sedan ut den insamlade informationen. Funktionen skriver ut

  • Totalt antal objekt;
  • Totalt antal filer;
  • Total storlek;
  • Detaljer om den största filen;
  • Lista över filer i katalogen.
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();
Kodbeskrivning
expand arrow
  • Rad 1: deklarerar en asynkron funktion med namnet main;

  • Rad 2: definierar variabeln directoryPath, som lagrar sökvägen till katalogen som ska analyseras;

  • Rad 3: anropar analyzeDirectory() med den angivna directoryPath och lagrar resultatet i variabeln directoryStats med hjälp av await;

  • Raderna 5-17: visar den beräknade katalogstatistiken med console.log(), inklusive totalt antal objekt, totalt antal filer, total storlek och information om den största filen;

  • Raderna 18-20: itererar genom arrayen fileList som lagras i directoryStats;

  • loggar namn och storlek för varje fil i katalogen;

  • Rad 23: anropar funktionen main() för att starta analysprocessen.

Komplett programkod

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();
Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 2. Kapitel 10

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Avsnitt 2. Kapitel 10
some-alt