File Size and Count in a Folder

A handy script I made with the help of AI to count the number of files by type and the size of each type of file

Rico

Rico Hancock

July 30th, 2024 5:34 PM

Hello Friends.

When it comes to my goal of posting a blog post every month, I'm a little behind 😂. I've been doing a ton of contract work, which eventually led me to a new job. That doesn't mean I've forgotten about blogging. I have a few blog posts that I've been working on, but I haven't posted them yet, so stay tuned.

Yesterday, I was working on a NodeJS script that I made with the help of AI to count the number of files by type and the size of each type of file. Honestly, I just wanted to see if one of my repositories was on the brink of a JavaScript-free existence. Spoiler: It's a work in progress. I've gotten the script to a pretty good place, so I'm going to share it with you. Keep in mind that this script is not perfect, but it's a good start.

Here's the code:

import fs from "fs"; import path from "path"; // The root directory to scan (current directory by default) const rootDir = process.cwd(); // Object to store counts and sizes per file extension const stats = {}; /** * Recursively scans directories and updates the stats object * @param {string} dir - The directory path to scan */ function scanDir(dir) { const files = fs.readdirSync(dir); for (const file of files) { const filePath = path.join(dir, file); // Skip symbolic links to avoid infinite loops if (fs.lstatSync(filePath).isSymbolicLink()) { continue; } const stat = fs.statSync(filePath); // Update folders as needed const excludeDirs = [ "node_modules", ".git", "dist", "build", ".yarn", ".circleci", ".cache", "storybook-static", ]; if (stat.isDirectory()) { if (excludeDirs.includes(file)) { continue; // Skip these directories } scanDir(filePath); // ... } else if (stat.isFile()) { const ext = path.extname(file).toLowerCase(); const extWithoutDot = ext ? ext.slice(1) : "[no ext]"; // Initialize the extension in stats if not already present if (!stats[extWithoutDot]) { stats[extWithoutDot] = { count: 0, size: 0 }; } // Update the count and size stats[extWithoutDot].count += 1; stats[extWithoutDot].size += stat.size; } // ... } } /** * Formats the file size into KB, MB, or GB as appropriate * @param {number} sizeInBytes - The size in bytes to format * @returns {string} - The formatted size string */ function formatSize(sizeInBytes) { const oneKB = 1024; const oneMB = 1024 * oneKB; const oneGB = 1024 * oneMB; if (sizeInBytes >= oneGB) { const sizeInGB = sizeInBytes / oneGB; return `${sizeInGB.toFixed(2)} GB`; } else if (sizeInBytes >= oneMB) { const sizeInMB = sizeInBytes / oneMB; return `${sizeInMB.toFixed(2)} MB`; } else { const sizeInKB = sizeInBytes / oneKB; return `${sizeInKB.toFixed(2)} KB`; } } // Start scanning from the root directory scanDir(rootDir); // Prepare data for console.table const data = []; for (const ext in stats) { data.push({ Extension: ext, Count: stats[ext].count, "Total Size": formatSize(stats[ext].size), }); } // Sort data by extension name data.sort((a, b) => a.Extension.localeCompare(b.Extension)); // Print the results in a table format console.table(data);

To use this script, you'll need to have NodeJS installed on your machine.

Save this script in your project's root directory as count-files.js (or something similar). Then, run the script with the following command:

node count-files.js

You should see a table show up in the terminal with that juicy stats.

You'll notice there is an excludeDirs array at the top of the script. You can add or remove directories from this array to exclude them from the scan. (I didn't really want to scan the entirety of node_modules, especially since I was going to be running this in a Monorepo. 😂)

That's it for me this month! Thanks for reading, enjoy your ice cream 🍦.