Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ ディレクトリ検査ツール | Node.jsとExpress.jsによるコンソールアプリケーションの構築
Node.jsとExpress.jsによるバックエンド開発

bookディレクトリ検査ツール

メニューを表示するにはスワイプしてください

この章では、DirInspect Pro という高度なコンソールアプリケーションを作成する課題を紹介します。このアプリは、任意のディレクトリを徹底的に分析し、そのファイルやサブディレクトリに関する有益な統計情報を取得することを可能にします。

チャレンジ

重要なファイルやデータが含まれるフォルダの迷路をナビゲートしなければならない状況を想像してください。DirInspect Pro はこの旅の頼もしい味方となり、ディレクトリ構造や内容について包括的な洞察を提供します。

完成するアプリ

DirInspect Pro の機能を活用する準備をしましょう。このアプリは、以下のような重要な情報を提供します。

  • アイテムの総数
  • すべてのアイテムの合計サイズ
  • 最大ファイルの名前とサイズ
  • 各ファイル名とサイズの詳細リスト

2つの選択肢

あなたの前には2つの選択肢があります。

  • 1つ目は、この課題に自力で取り組み、ガイダンスなしでスキルを磨く道;
  • 2つ目は、成功を保証する有益なガイドに従う道。

どちらを選んでも、魅力的で実用的なコンソールアプリの作成という、やりがいのある旅が待っています。

マスタープラン

  • ステップ1:必要なモジュールのインポート;
  • ステップ2:getStats関数の定義;
  • ステップ3:analyzeFile関数の定義;
  • ステップ4:analyzeDirectory関数の定義;
  • ステップ5:main関数の定義と実行;
  • まとめ;
  • アプリ全体のコード。

ステップ1:必要なモジュールのインポート

この冒険を始めるには、適切なツールが必要です。まず、2つの主要なモジュールをインポートします:ファイルシステムを非同期で管理するためのfs.promisesと、ファイルパスを効果的に扱うためのpathです。

const fs = require("fs").promises;
const path = require("path");

ステップ2: getStats関数の定義

非同期関数getStatsは、ファイルまたはディレクトリのパスを引数として受け取り、fs.statを使用してその統計情報の取得を試みます。

  • 成功した場合は統計情報を返却
  • エラーが発生した場合はエラーメッセージをログに出力し、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;
  }
}

ステップ3: analyzeFile関数の定義

analyzeFile関数は、getStats関数を利用してファイルの統計情報を取得します。統計情報が取得できた場合(nullでない場合)、ファイル名(path.basenameで抽出)とサイズを含むオブジェクトを返却します。

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

  return {
    name: path.basename(filePath),
    size: stats.size,
  };
}

ステップ4: analyzeDirectory関数の定義

analyzeDirectory関数は、ディレクトリを走査し、その内容に関する詳細な統計情報を収集します。 動作概要: ディレクトリ内のすべての項目をfs.readdirで読み込みます。各項目について:

  • path.joinでフルパスを生成
  • getStatsでファイルかフォルダかを判定
  • ファイルの場合:
    • analyzeFileを呼び出して{ name, size }を取得
    • 合計、最大ファイル、ファイルリストを更新
  • ディレクトリの場合:
    • 再帰的にanalyzeDirectoryを呼び出し
    • 結果を現在の統計情報に統合
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: []
    };
  }
}

ステップ5: main関数の定義と呼び出し

main関数はスクリプトのエントリーポイントです。この関数では解析対象のディレクトリパス(この例では./docs)を指定し、analyzeDirectory関数を呼び出してディレクトリおよびその内容の統計情報を取得し、収集した情報を出力します。 この関数は以下を出力します。

  • アイテムの総数
  • ファイルの総数
  • 合計サイズ
  • 最大ファイルの詳細
  • ディレクトリ内のファイル一覧
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();

アプリ全体のコード

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();
すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 2.  10

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 2.  10
some-alt