Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Hakemiston Tarkastustyökalu | Konsolisovellusten Rakentaminen Node.js:llä
Backend-kehitys Node.js:llä ja Express.js:llä

Hakemiston Tarkastustyökalu

Pyyhkäise näyttääksesi valikon

Tässä luvussa esitellään haaste: kehittyneen konsolisovelluksen nimeltä DirInspect Pro luominen. Tämän sovelluksen avulla voit analysoida minkä tahansa hakemiston perusteellisesti ja saada kattavat tilastot sen tiedostoista ja alihakemistoista.

Haaste

Kuvittele tilanne, jossa sinun täytyy navigoida kansioiden labyrintissä, joka sisältää tärkeitä tiedostoja ja dataa. DirInspect Pro on apunasi tällä matkalla, tarjoten kattavaa tietoa hakemiston rakenteesta ja sisällöstä.

Lopullinen sovellus

Valmistaudu hyödyntämään DirInspect Pro:n ominaisuuksia. Sovellus tarjoaa keskeistä tietoa, kuten

  • Kohteiden kokonaismäärä;
  • Kaikkien kohteiden yhteenlaskettu koko;
  • Suurimman tiedoston nimi ja koko;
  • Yksittäisten tiedostojen nimet ja koot yksityiskohtaisesti.

Kaksi polkua valittavana

Edessäsi on kaksi polkua.

  • Ensimmäinen on tarttua haasteeseen suoraan, kehittäen taitojasi ilman ohjausta;
  • Toinen on seurata hyödyllistä opasta, joka takaa onnistumisesi.

Valitsitpa kumman tahansa, edessäsi on palkitseva matka, jonka lopputuloksena syntyy kiehtova ja toimiva konsolisovellus.

Pääsuunnitelma

  • Vaihe 1: Tarvittavien moduulien tuonti;
  • Vaihe 2: getStats-funktion määrittely;
  • Vaihe 3: analyzeFile-funktion määrittely;
  • Vaihe 4: analyzeDirectory-funktion määrittely;
  • Vaihe 5: main-funktion määrittely ja kutsuminen;
  • Yhteenveto;
  • Sovelluksen koko koodi.

Vaihe 1: Tarvittavien moduulien tuonti

Tämän projektin aloittamiseen tarvitset oikeat työkalut. Aloita tuomalla kaksi keskeistä moduulia: fs.promises tiedostojärjestelmän asynkroniseen hallintaan ja path tiedostopolkujen käsittelyyn tehokkaasti.

const fs = require("fs").promises;
const path = require("path");
Koodin kuvaus
expand arrow
  • Rivi 1: tuo sisäänrakennetun fs-moduulin. .promises-ominaisuus tarjoaa pääsyn lupauksiin perustuvaan API:iin, mahdollistaen asynkroniset tiedosto-operaatiot async/await-rakenteella;
  • Rivi 2: tuo sisäänrakennetun path-moduulin. Tämä moduuli tarjoaa apuvälineitä tiedosto- ja hakemistopolkujen käsittelyyn, mukaan lukien polkujen muokkaus ja normalisointi.

Vaihe 2: getStats-funktion määrittely

Asynkroninen funktio getStats ottaa tiedoston tai hakemiston polun argumenttina ja yrittää hakea sen tilastotiedot käyttäen fs.stat-metodia.

  • Onnistuneessa tapauksessa palauttaa tilastotiedot;
  • Virheen sattuessa kirjaa virheilmoituksen ja palauttaa 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;
  }
}
Koodin kuvaus
expand arrow
  • Rivi 1: määrittelee asynkronisen funktion nimeltä getStats, joka ottaa parametrina filePath;
  • Rivit 2, 5: luovat try...catch-lohkon virheenkäsittelyä varten asynkronisen operaation aikana;
  • Rivi 3: käyttää await fs.stat(filePath) hakeakseen tietoa määritetystä tiedostosta, kuten koko, luontiaika ja muuta metadataa;
  • Rivi 4: palauttaa stats-olion, jos fs.stat()-operaatio onnistuu;
  • Rivi 6: kirjaa virheilmoituksen konsoliin käyttäen console.error(), jos operaatio epäonnistuu;
  • Rivi 7: palauttaa null osoittaakseen, että tiedoston tilastotietoja ei voitu hakea.

Vaihe 3: analyzeFile-funktion määrittely

Funktio analyzeFile käyttää getStats-funktiota hakeakseen tiedoston tilastotiedot. Jos tilastotiedot ovat saatavilla (ei null), funktio palauttaa olion, joka sisältää tiedoston nimen (haettu path.basename-metodilla) ja sen koon.

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

  return {
    name: path.basename(filePath),
    size: stats.size,
  };
}
Koodin kuvaus
expand arrow
  • Rivi 1: määrittelee asynkronisen funktion nimeltä analyzeFile, joka ottaa parametrina filePath;
  • Rivi 2: käyttää await getStats(filePath) hakeakseen tiedoston tilastot annetulle polulle;
  • Rivi 3: tarkistaa, onko stats epätosi. Jos tilastoja ei saatu haettua, funktio palauttaa null;
  • Rivit 5-8: luovat ja palauttavat olion, joka sisältää tiedoston nimen ja koon. Tiedoston nimi haetaan path.basename(filePath)-funktiolla ja koko stats.size-kentästä.

Vaihe 4: analyzeDirectory-funktion määrittely

analyzeDirectory-funktio skannaa hakemiston ja kerää kattavat tilastot sen sisällöstä. Toimintaperiaate: se lukee kaikki hakemiston kohteet käyttäen fs.readdir. Jokaiselle kohteelle:

  • Rakentaa täyden polun path.join-funktiolla;
  • Käyttää getStats-funktiota tunnistaakseen, onko kyseessä tiedosto vai kansio;
  • Jos kyseessä on tiedosto:
    • Kutsuu analyzeFile-funktiota saadakseen { name, size };
    • Päivittää kokonaismäärät, suurimman tiedoston ja tiedostolistan.
  • Jos kyseessä on hakemisto:
    • Kutsuu rekursiivisesti analyzeDirectory-funktiota;
    • Yhdistää tulokset nykyisiin tilastoihin.
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: []
    };
  }
}
Koodin kuvaus
expand arrow
  • Rivi 1: määrittelee asynkronisen funktion nimeltä analyzeDirectory, joka ottaa parametrina directoryPath;

  • Rivit 2-6: alustavat muuttujat hakemiston tilastojen tallentamista varten, mukaan lukien kokonaismäärä, tiedostojen määrä, kokonaiskoko, suurin tiedosto ja analysoitujen tiedostojen lista;

  • Rivi 8: aloittaa try-lohkon mahdollisten tiedostojärjestelmävirheiden käsittelemiseksi;

  • Rivi 9: lukee hakemiston sisällön käyttäen fs.readdir() ja tallentaa tuloksen items-taulukkoon;

  • Rivi 11: aloittaa for...of-silmukan, joka käy läpi jokaisen hakemiston kohteen;

  • Rivi 12: luo nykyisen kohteen täyden polun käyttäen path.join();

  • Rivi 13: hakee nykyisen kohteen tilastot getStats()-funktiolla;

  • Rivi 14: ohittaa nykyisen kohteen, jos sen tilastoja ei saatu haettua;

  • Rivi 16: kasvattaa totalItems-arvoa jokaisesta onnistuneesti käsitellystä tiedostosta tai kansiosta;

  • Rivit 18-29: käsittelevät tiedostojen prosessointia:

    • Rivi 19: kutsuu analyzeFile()-funktiota saadakseen tiedoston nimen ja koon;
  • Rivi 20: ohittaa tiedoston, jos analyysi epäonnistuu;

    • Rivit 22-23: päivittävät tiedostojen kokonaismäärän ja kertyneen koon;
    • Rivit 25-27: päivittävät largestFile-arvon, jos nykyinen tiedosto on suurempi kuin aiemmin tallennettu;
    • Rivi 29: lisää tiedoston tiedot fileList-listaan;
  • Rivit 30-42: käsittelevät hakemistojen prosessointia:

    • Rivi 31: kutsuu rekursiivisesti analyzeDirectory()-funktiota alihakemistolle;
    • Rivit 33-35: yhdistävät alihakemiston tilastot nykyisiin kokonaisarvoihin;
    • Rivit 37-39: päivittävät largestFile-arvon, jos alihakemistossa on suurempi tiedosto;
    • Rivi 41: yhdistää tiedostolistat käyttäen concat()-funktiota;
  • Rivit 45-50: palauttavat olion, joka sisältää lopulliset hakemiston tilastot;

  • Rivit 52-62: käsittelevät virheet tulostamalla viestin ja palauttamalla oletustilasto-olion.

Vaihe 5: Määrittele main-funktio ja kutsu se

main-funktio toimii skriptin aloituspisteenä. Se määrittää analysoitavan hakemiston polun (tässä tapauksessa ./docs), kutsuu analyzeDirectory-funktiota saadakseen hakemiston ja sen sisällön tilastotiedot, ja tulostaa kerätyt tiedot. Funktio tulostaa:

  • Kohteiden kokonaismäärän;
  • Tiedostojen kokonaismäärän;
  • Kokonaiskoon;
  • Suurimman tiedoston tiedot;
  • Hakemiston tiedostoluettelon.
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();
Koodin kuvaus
expand arrow
  • Rivi 1: määrittelee asynkronisen funktion nimeltä main;

  • Rivi 2: määrittää muuttujan directoryPath, joka tallentaa analysoitavan hakemiston polun;

  • Rivi 3: kutsuu analyzeDirectory()-funktiota annetulla directoryPath-polulla ja tallentaa tuloksen muuttujaan directoryStats käyttäen await-avainsanaa;

  • Rivit 5-17: näyttävät lasketut hakemiston tilastotiedot käyttäen console.log(), mukaan lukien kohteiden kokonaismäärän, tiedostojen kokonaismäärän, kokonaiskoon sekä suurimman tiedoston tiedot;

  • Rivit 18-20: käyvät läpi fileList-muuttujassa olevan directoryStats-taulukon;

  • tulostavat jokaisen tiedoston nimen ja koon hakemistossa;

  • Rivi 23: kutsuu main()-funktiota käynnistääkseen analyysiprosessin.

Sovelluksen koko koodi

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();
Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 10

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Osio 2. Luku 10
some-alt