Get all files recursively in directories NodejS

node.jsFsGetfiles

node.js Problem Overview


I have a little problem with my function. I would like to get all files in many directories. Currently, I can retrieve the files in the file passed in parameters. I would like to retrieve the html files of each folder in the folder passed as a parameter. I will explain if I put in parameter "test" I retrieve the files in "test" but I would like to retrieve "test / 1 / *. Html", "test / 2 / . /.html ":

var srcpath2 = path.join('.', 'diapo', result);
function getDirectories(srcpath2) {
                return fs.readdirSync(srcpath2).filter(function (file) {
                    return fs.statSync(path.join(srcpath2, file)).isDirectory();
                });
            }

The result : [1,2,3]

thanks !

node.js Solutions


Solution 1 - node.js

It looks like the glob npm package would help you. Here is an example of how to use it:

File hierarchy:

test
├── one.html
└── test-nested
    └── two.html

JS code:

const glob = require("glob");

var getDirectories = function (src, callback) {
  glob(src + '/**/*', callback);
};
getDirectories('test', function (err, res) {
  if (err) {
    console.log('Error', err);
  } else {
    console.log(res);
  }
});

which displays:

[ 'test/one.html',  'test/test-nested',  'test/test-nested/two.html' ]

Solution 2 - node.js

I've seen many very long answers, and it's kinda a waste of memory space. Some also use packages like glob, but if you don't want to depend on any package, here's my solution.

const Path = require("path");
const FS   = require("fs");
let Files  = [];

function ThroughDirectory(Directory) {
    FS.readdirSync(Directory).forEach(File => {
        const Absolute = Path.join(Directory, File);
        if (FS.statSync(Absolute).isDirectory()) return ThroughDirectory(Absolute);
        else return Files.push(Absolute);
    });
}

ThroughDirectory("./input/directory/");

It's pretty self-explanatory. There's an input directory, and it iterates through that. If one of the items is also a directory, go through that and so on. If it's a file, add the absolute path to the array.

Hope this helped :]

Solution 3 - node.js

Using ES6 yield

const fs = require('fs');
const path = require('path');

function *walkSync(dir) {
  const files = fs.readdirSync(dir, { withFileTypes: true });
  for (const file of files) {
    if (file.isDirectory()) {
      yield* walkSync(path.join(dir, file.name));
    } else {
      yield path.join(dir, file.name);
    }
  }
}

for (const filePath of walkSync(__dirname)) {
  console.log(filePath);
}

Solution 4 - node.js

Here's mine. Like all good answers it's hard to understand:

const isDirectory = path => statSync(path).isDirectory();
const getDirectories = path =>
    readdirSync(path).map(name => join(path, name)).filter(isDirectory);

const isFile = path => statSync(path).isFile();  
const getFiles = path =>
    readdirSync(path).map(name => join(path, name)).filter(isFile);

const getFilesRecursively = (path) => {
    let dirs = getDirectories(path);
    let files = dirs
        .map(dir => getFilesRecursively(dir)) // go through each directory
        .reduce((a,b) => a.concat(b), []);    // map returns a 2d array (array of file arrays) so flatten
    return files.concat(getFiles(path));
};

Solution 5 - node.js

I really liked Smally's Solution but didn't like the Syntax.

Same solution but slightly easier to read:

const fs = require("fs");
const path = require("path");
let files = [];

const getFilesRecursively = (directory) => {
  const filesInDirectory = fs.readdirSync(directory);
  for (const file of filesInDirectory) {
    const absolute = path.join(directory, file);
    if (fs.statSync(absolute).isDirectory()) {
        getFilesRecursively(absolute);
    } else {
        files.push(absolute);
    }
  }
};

Solution 6 - node.js

With modern JavaScript (NodeJs 10) you can use async generator function and loop through them using for-await...of

// ES modules syntax that is included by default in NodeJS 14.
// For earlier versions, use `--experimental-modules` flag
import fs from "fs/promises"

// or, without ES modules, use this:
// const fs = require('fs').promises

async function run() {
  for await (const file of getFiles()) {
    console.log(file.path)
  }
}

async function* getFiles(path = `./`) {
  const entries = await fs.readdir(path, { withFileTypes: true })

  for (let file of entries) {
    if (file.isDirectory()) {
      yield* getFiles(`${path}${file.name}/`)
    } else {
      yield { ...file, path: path + file.name }
    }
  }
}

run()

Solution 7 - node.js

Packed into library: https://www.npmjs.com/package/node-recursive-directory

https://github.com/vvmspace/node-recursive-directory

List of files:

const getFiles = require('node-recursive-directory');

(async () => {
    const files = await getFiles('/home');
    console.log(files);
})()

List of files with parsed data:

const getFiles = require('node-resursive-directory');
 
(async () => {
    const files = await getFiles('/home', true); // add true
    console.log(files);
})()

You will get something like that:

  [
      ...,
      {
        fullpath: '/home/vvm/Downloads/images/Some/Some Image.jpg',
        filepath: '/home/vvm/Downloads/images/Some/',
        filename: 'Some Image.jpg',
        dirname: 'Some'
    },
  ]

Solution 8 - node.js

You can also write your own code like below to traverse the directory as shown below :

var fs = require('fs');
function traverseDirectory(dirname, callback) {
  var directory = [];
  fs.readdir(dirname, function(err, list) {
    dirname = fs.realpathSync(dirname);
    if (err) {
      return callback(err);
    }
    var listlength = list.length;
    list.forEach(function(file) {
      file = dirname + '\\' + file;
      fs.stat(file, function(err, stat) {
        directory.push(file);
 if (stat && stat.isDirectory()) {
          traverseDirectory(file, function(err, parsed) {
     directory = directory.concat(parsed);
     if (!--listlength) {
       callback(null, directory);
     }
   });
 } else {
     if (!--listlength) {
       callback(null, directory);
     }
          }
      });
    });
  });
}
traverseDirectory(__dirname, function(err, result) {
  if (err) {
    console.log(err);
  }
  console.log(result);
});

You can check more information about it here : http://www.codingdefined.com/2014/09/how-to-navigate-through-directories-in.html

Solution 9 - node.js

I needed to so something similar, in an Electron app: get all subfolders in a given base folder, using TypeScript, and came up with this:

import { readdirSync, statSync, existsSync } from "fs";
import * as path from "path";

// recursive synchronous "walk" through a folder structure, with the given base path
getAllSubFolders = (baseFolder, folderList = []) => {

    let folders:string[] = readdirSync(baseFolder).filter(file => statSync(path.join(baseFolder, file)).isDirectory());
    folders.forEach(folder => {
        folderList.push(path.join(baseFolder,folder));
        this.getAllSubFolders(path.join(baseFolder,folder), folderList);
    });
}

Solution 10 - node.js

const fs = require('fs');
const path = require('path');
var filesCollection = [];
const directoriesToSkip = ['bower_components', 'node_modules', 'www', 'platforms'];

function readDirectorySynchronously(directory) {
    var currentDirectorypath = path.join(__dirname + directory);

    var currentDirectory = fs.readdirSync(currentDirectorypath, 'utf8');

    currentDirectory.forEach(file => {
        var fileShouldBeSkipped = directoriesToSkip.indexOf(file) > -1;
        var pathOfCurrentItem = path.join(__dirname + directory + '/' + file);
        if (!fileShouldBeSkipped && fs.statSync(pathOfCurrentItem).isFile()) {
            filesCollection.push(pathOfCurrentItem);
        }
        else if (!fileShouldBeSkipped) {
            var directorypath = path.join(directory + '\\' + file);
            readDirectorySynchronously(directorypath);
        }
    });
}

readDirectorySynchronously('');

This will fill filesCollection with all the files in the directory and its subdirectories (it's recursive). You have the option to skip some directory names in the directoriesToSkip array.

Solution 11 - node.js

Speaking of npm packages - another short option is to use fs-readdir-recursive:

const read = require("fs-readdir-recursive");
const foundFiles = read("test");
console.log(foundFiles);

Output:

[ 'one.html', 'test-nested/some_text.txt', 'test-nested/two.html' ]

If you're interested only in files with specific extension (like .html mentioned in the question) you can filter them using .endsWith():

const filteredFiles = read("test").filter(item => item.endsWith(".html"));

Solution 12 - node.js

You can use loop through all the files and directories of the root folder, if it's a directory, then get inside it and repeat the process. Consider the code below:

const fs = require('fs');
const path = require('path');

const target = './'; // choose the directory to target
var result = []
var filePaths = []
var tempFolder = []
const targetPath = fs.readdirSync(target);




function hit(mainPath = targetPath) {

  mainPath.forEach((file) => {

    let check = fs.statSync(file);

    if (!check.isDirectory()) {
      filePaths.push(file)
    }
    else {
      if (file[0] != '.') {
        tempFolder.push(file)
      }
    }
  });

  // get files from folder
  if (tempFolder.length > 0) {
    tempFolder.forEach((dir) => {
      getFiles(dir)
    })
  } 
   // filePaths contains path to every file

}




function getFiles(dir) {

  var paths = fs.readdirSync(dir);
  var files = [];

  paths.forEach(function (file) {
    var fullPath = dir + '/' + file;
    files.push(fullPath);
  });

  files.forEach((tempFile) => {
    let check = fs.statSync(tempFile);

    if (check.isDirectory()) {
      getFiles(tempFile)
    } else {
      filePaths.push(tempFile)
    }
  })
}



hit(); // main function

Solution 13 - node.js

If you rather work synchronously with glob, use the glob.sync() function as mentioned in their documentation. Here's the equivalent example provided by @Paul Mougel but written synchronously:

const glob = require("glob");

var getDirectories = function (src) {
  return glob.sync(src + '/**/*');
};
var rest = getDirectories('test');
console.log(res);

Solution 14 - node.js

Here is a compact pure function that returns all the paths (relatives) in the directory.

const getFilesPathsRecursively = (directory: string, origin?: string): string[] =>
  fs.readdirSync(directory).reduce((files, file) => {
    const absolute = path.join(directory, file)
    return [
      ...files,
      ...(fs.statSync(absolute).isDirectory()
        ? getFilesPathsRecursively(absolute, origin || directory)
        : [path.relative(origin || directory, absolute)]),
    ]
  }, [])

Solution 15 - node.js

A solution with Promises based on globby:

import { globby } from 'globby';

(async () => {
  const path = '/path/to/dir';
  const files = await globby([`${path}/**/*`]);

  console.log(files);
  // [ 
  //   '/path/to/dir/file1.txt', 
  //   '/path/to/dir/subdir/file2.txt', 
  //   ... 
  // ]
})()

Solution 16 - node.js

Although not perfect in some scenarios, it must be helpful in many.

const getAllFilePath = (path: string) => {
    const addData = (_paths: string[]) => {
        const newFoldersToScrape: string[] = [];

        _paths.forEach(_path => {
            fs.readdirSync(_path).forEach((file: string) => {
                if (file.indexOf(".") === -1) {
                    newFoldersToScrape.push(`${_path}/${file}`);
                } else {
                    filePaths.push(`${_path}/${file}`);
                }
            });
        });

        foldersToScrape = newFoldersToScrape;
    };

    const baseDirPath = `<YOUR BASE PATH HERE>/${path}`;
    let foldersToScrape: string[] = [];
    const filePaths: string[] = [];

    addData([baseDirPath]);

    while (foldersToScrape.length !== 0) {
        addData(foldersToScrape);
    }

    return filePaths;
};

Solution 17 - node.js

I did mine with typescript works well fairly easy to understand

    import * as fs from 'fs';
    import * as path from 'path';

    export const getAllSubFolders = (
      baseFolder: string,
      folderList: string[] = []
    ) => {
      const folders: string[] = fs
        .readdirSync(baseFolder)
        .filter(file => fs.statSync(path.join(baseFolder, file)).isDirectory());
      folders.forEach(folder => {
        folderList.push(path.join(baseFolder, folder));
        getAllSubFolders(path.join(baseFolder, folder), folderList);
      });
      return folderList;
    };
    export const getFilesInFolder = (rootPath: string) => {
      return fs
        .readdirSync(rootPath)
        .filter(
          filePath => !fs.statSync(path.join(rootPath, filePath)).isDirectory()
        )
        .map(filePath => path.normalize(path.join(rootPath, filePath)));
    };
    export const getFilesRecursively = (rootPath: string) => {
      const subFolders: string[] = getAllSubFolders(rootPath);
      const allFiles: string[][] = subFolders.map(folder =>
        getFilesInFolder(folder)
      );
      return [].concat.apply([], allFiles);
    };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser6285277View Question on Stackoverflow
Solution 1 - node.jsPaul MougelView Answer on Stackoverflow
Solution 2 - node.jsSmallyView Answer on Stackoverflow
Solution 3 - node.jsStephenView Answer on Stackoverflow
Solution 4 - node.jsuser875234View Answer on Stackoverflow
Solution 5 - node.jsarthurDentView Answer on Stackoverflow
Solution 6 - node.jsmikabytesView Answer on Stackoverflow
Solution 7 - node.jsVladimir MyagdeevView Answer on Stackoverflow
Solution 8 - node.jsCodingDefinedView Answer on Stackoverflow
Solution 9 - node.jsBenView Answer on Stackoverflow
Solution 10 - node.jsvvn050View Answer on Stackoverflow
Solution 11 - node.jsZukuView Answer on Stackoverflow
Solution 12 - node.jsNitin ManochaView Answer on Stackoverflow
Solution 13 - node.jsArmando HoyosView Answer on Stackoverflow
Solution 14 - node.jsCorentinView Answer on Stackoverflow
Solution 15 - node.jsCimChdView Answer on Stackoverflow
Solution 16 - node.jsvaskrneupView Answer on Stackoverflow
Solution 17 - node.jsChris SpranceView Answer on Stackoverflow