Bhaumik Bhatt
Bhaumik Bhatt

Reputation: 490

Files array return undefined in readdir

I am trying to read all the files inside a nested folder. I am able to reach the innermost layer of directory but when I tried readdir method on the folders (that contains the files I want to use) the readdir method returned undefined in files array

My directory structure is like this.

main directory=logs which contains many directories like logs_of_29,logs_of_19 each of these contains different folders with names like 157486185 and each of those contains logs files

so the path to the file I am trying to read content of will be

logs\logs_of_41\1565605874284\file.json

How do I read data of this nested file

I have tried following

var http = require('http');
var fs = require('fs');
http.createServer(function (requests, response) {
    handle_files()
}).listen(8080)

handle_files = () => {
    // get the list of directories of logs_of_109
    fs.readdir('logs_of_109', function (error, files) {
        files.map(file => {
            var sub_directory = file
            // get list of all the directories inside logs_of_109 subfolders
            fs.readdir('logs_of_109/' + sub_directory, function (error, files) {
                var sub_directory2 = files
                console.log('logs_of_109/' + sub_directory + sub_directory2)
                files.map(file => {
                    fs.readdir('logs_of_109/' + sub_directory + sub_directory2, function (error, files) {
                        files.map(file => { console.log(file) })
                    })
                })
            })
        })
    })
}

Now the file in the innermost loop gives me undefined. Also this approach is very repetitive. Is there any better way to do this and can someone explain why file array is logging undefined on the console

Upvotes: 0

Views: 335

Answers (1)

Terry Lennox
Terry Lennox

Reputation: 30685

I would suggest using a recursive approach, this is normally the easiest way to proceed with this kind of problem. The code below should accomplish what you wish. The server will respond with a list of files in the specified folder:

const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const getStats = promisify(fs.stat);
const readdir = promisify(fs.readdir);
const http = require('http');

handle_files = async (req, res) => {
    let files = await scanDir("logs_of_109");
    console.log(`Scan complete, file count: ${files.length}`);
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write(files.join(", "));
    res.end();
};

http.createServer(handle_files).listen(8080)

async function scanDir(dir, includeDirectories = false, fileList = []) {

    let files = await readdir(dir);
    for(let file of files) {
        let filePath = path.join(dir, file);

        try {
            let stats = await getStats(filePath);
            let isDirectory = stats.isDirectory();
            if (includeDirectories || !isDirectory) {
                fileList.push(filePath);
            }
            if (stats.isDirectory()) {
                await scanDir(filePath, fileList);
            }
        } catch (err) {
            // Drop on the floor.. 
        }
    }

    return fileList;   
}

Upvotes: 1

Related Questions