JavaScript Development Space

Get All Directories and Files Within Directory in NodeJs

Basic Setup and Installation

First, create a new Node.js project and ensure it supports ES modules by adding this to your package.json:

json
1 {
2 "type": "module"
3 }

Create two files:

  1. fileExplorer.js - Contains the core functionality
  2. main.js - Contains usage examples

Core Implementation (fileExplorer.js)

js
1 import { promises as fsPromises } from 'fs';
2 import { join, extname } from 'path';
3
4 // Main function to get files and directories
5 export async function getFilesAndDirs(dirPath, options = {}) {
6 const {
7 recursive = false,
8 filePattern = null,
9 dirPattern = null
10 } = options;
11
12 const result = {
13 files: [],
14 directories: []
15 };
16
17 try {
18 const entries = await fsPromises.readdir(dirPath, { withFileTypes: true });
19
20 for (const entry of entries) {
21 const fullPath = join(dirPath, entry.name);
22
23 if (entry.isDirectory()) {
24 if (!dirPattern || dirPattern.test(entry.name)) {
25 result.directories.push(fullPath);
26 }
27
28 if (recursive) {
29 const subResults = await getFilesAndDirs(fullPath, options);
30 result.files.push(...subResults.files);
31 result.directories.push(...subResults.directories);
32 }
33 } else if (entry.isFile()) {
34 if (!filePattern || filePattern.test(entry.name)) {
35 result.files.push(fullPath);
36 }
37 }
38 }
39
40 return result;
41 } catch (error) {
42 throw new Error(`Failed to read directory: ${error.message}`);
43 }
44 }
45
46 // Get detailed file information
47 export async function getDetailedInfo(dirPath) {
48 try {
49 const entries = await fsPromises.readdir(dirPath, { withFileTypes: true });
50 const result = {
51 files: [],
52 directories: []
53 };
54
55 for (const entry of entries) {
56 const fullPath = join(dirPath, entry.name);
57 const stats = await fsPromises.stat(fullPath);
58
59 const baseInfo = {
60 name: entry.name,
61 path: fullPath,
62 size: stats.size,
63 created: stats.birthtime,
64 modified: stats.mtime
65 };
66
67 if (entry.isDirectory()) {
68 result.directories.push({
69 ...baseInfo,
70 type: 'directory'
71 });
72 } else if (entry.isFile()) {
73 result.files.push({
74 ...baseInfo,
75 type: 'file',
76 extension: extname(entry.name)
77 });
78 }
79 }
80
81 return result;
82 } catch (error) {
83 throw new Error(`Failed to get detailed information: ${error.message}`);
84 }
85 }
86
87 // File size formatter utility
88 export function formatFileSize(bytes) {
89 const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
90 if (bytes === 0) return '0 Bytes';
91 const i = Math.floor(Math.log(bytes) / Math.log(1024));
92 return `${Math.round(bytes / Math.pow(1024, i))} ${sizes[i]}`;
93 }
94
95 // Utility functions
96 export const utils = {
97 createFilePattern: (...extensions) => {
98 const pattern = extensions.map(ext => `\\.${ext.replace(/^\./, '')}`).join('|');
99 return new RegExp(`(${pattern})$`);
100 },
101
102 async isAccessible(path) {
103 try {
104 await fsPromises.access(path);
105 return true;
106 } catch {
107 return false;
108 }
109 }
110 };

Usage Examples (main.js)

js
1 import {
2 getFilesAndDirs,
3 getDetailedInfo,
4 formatFileSize,
5 utils
6 } from './fileExplorer.js';
7
8 // Basic directory scanning
9 async function basicExample() {
10 try {
11 const result = await getFilesAndDirs('./my-directory');
12 console.log('Files:', result.files);
13 console.log('Directories:', result.directories);
14 } catch (error) {
15 console.error('Error:', error.message);
16 }
17 }
18
19 // Recursive scanning with filters
20 async function advancedExample() {
21 try {
22 const result = await getFilesAndDirs('./my-directory', {
23 recursive: true,
24 filePattern: utils.createFilePattern('js', 'ts'), // Only JavaScript and TypeScript files
25 dirPattern: /^(?!node_modules).*/ // Exclude node_modules directory
26 });
27 console.log('JavaScript and TypeScript files:', result.files);
28 } catch (error) {
29 console.error('Error:', error.message);
30 }
31 }
32
33 // Getting detailed file information
34 async function detailedExample() {
35 try {
36 const details = await getDetailedInfo('./my-directory');
37 details.files.forEach(file => {
38 console.log(`
39 File: ${file.name}
40 Size: ${formatFileSize(file.size)}
41 Created: ${file.created}
42 Modified: ${file.modified}
43 Extension: ${file.extension}
44 `);
45 });
46 } catch (error) {
47 console.error('Error:', error.message);
48 }
49 }
50
51 // Run all examples
52 async function runExamples() {
53 console.log('--- Basic Example ---');
54 await basicExample();
55
56 console.log('\n--- Advanced Example ---');
57 await advancedExample();
58
59 console.log('\n--- Detailed Example ---');
60 await detailedExample();
61 }
62
63 runExamples();

Common Use Cases

1. List All JavaScript Files

js
1 const jsFiles = await getFilesAndDirs('./src', {
2 recursive: true,
3 filePattern: /\.js$/
4 });
5 console.log('JavaScript files:', jsFiles.files);

2. Get Size of All Images

js
1 const imagePattern = utils.createFilePattern('jpg', 'png', 'gif');
2 const details = await getDetailedInfo('./images');
3 const totalSize = details.files
4 .filter(file => imagePattern.test(file.name))
5 .reduce((total, file) => total + file.size, 0);
6
7 console.log('Total image size:', formatFileSize(totalSize));

3. Find Large Files

js
1 const details = await getDetailedInfo('./');
2 const largeFiles = details.files
3 .filter(file => file.size > 1024 * 1024) // Files larger than 1MB
4 .sort((a, b) => b.size - a.size);
5
6 largeFiles.forEach(file => {
7 console.log(`${file.name}: ${formatFileSize(file.size)}`);
8 });

4. Check for Empty Directories

js
1 async function findEmptyDirs(dirPath) {
2 const result = await getFilesAndDirs(dirPath, { recursive: true });
3 const emptyDirs = [];
4
5 for (const dir of result.directories) {
6 const contents = await getFilesAndDirs(dir);
7 if (contents.files.length === 0 && contents.directories.length === 0) {
8 emptyDirs.push(dir);
9 }
10 }
11
12 return emptyDirs;
13 }

Error Handling Examples

js
1 async function safeDirectoryOperation(dirPath) {
2 try {
3 // Check if directory exists and is accessible
4 const isAccessible = await utils.isAccessible(dirPath);
5 if (!isAccessible) {
6 throw new Error('Directory is not accessible');
7 }
8
9 const result = await getFilesAndDirs(dirPath, {
10 recursive: true
11 });
12
13 return result;
14 } catch (error) {
15 if (error.code === 'ENOENT') {
16 console.error('Directory does not exist:', dirPath);
17 } else if (error.code === 'EACCES') {
18 console.error('Permission denied:', dirPath);
19 } else {
20 console.error('Unexpected error:', error.message);
21 }
22 return null;
23 }
24 }

Best Practices

  1. Always use try-catch blocks for error handling
  2. Use the utility functions for consistent patterns
  3. Consider memory usage with recursive operations
  4. Check directory accessibility before operations
  5. Use async/await for cleaner code
  6. Format file sizes for better readability

Remember to handle errors appropriately and consider performance implications when dealing with large directories or deep recursive operations.

JavaScript Development Space

© 2024 JavaScript Development Space - Master JS and NodeJS. All rights reserved.