'Nodejs readdir - only find files

When reading a directory, I currently have this:

  fs.readdir(tests, (err, items) => {

      if(err){
        return cb(err);
      }

      const cmd = items.filter(v => fs.lstatSync(tests + '/' + v).isFile());

      k.stdin.end(`${cmd}`);
  });

first of all I need a try/catch in there around fs.lstatSync, which I don't want to add. But is there a way to use fs.readdir to only find files?

Something like:

fs.readdir(tests, {type:'f'}, (err, items) => {});

does anyone know how?



Solution 1:[1]

Unfortunately, fs.readdir doesn't have an option to specify that you're only looking for files, not folders/directories (per docs). Filtering the results from fs.readdir to knock out the directories is your best bet.

https://nodejs.org/dist/latest-v10.x/docs/api/fs.html#fs_fs_readdir_path_options_callback

The optional options argument can be a string specifying an encoding, or an object with an encoding property specifying the character encoding to use for the filenames passed to the callback. If the encoding is set to 'buffer', the filenames returned will be passed as Buffer objects.

Solution 2:[2]

Starting from node v10.10.0, you can add withFileTypes as options parameter to get fs.Dirent instead of string.

// or readdir to get a promise
const subPaths = fs.readdirSync(YOUR_BASE_PATH, { 
  withFileTypes: true
});
// subPaths is fs.Dirent[] type
const directories = subPaths.filter((dirent) => dirent.isFile());
// directories is string[] type

more info is located at node documentation:

Solution 3:[3]

Yeah fs.readdir can't do this currently (only read files or only read dirs).

I filed an issue with Node.js and looks like it may be a good feature to add.

https://github.com/nodejs/node/issues/21804

Solution 4:[4]

If your use case is scripting/automation. You might try fs-jetpack library. That can find files in folder for you, but also can be configured for much more sophisticated searches.

const jetpack = require("fs-jetpack");

// Find all files in my_folder
const filesInFolder = jetpack.find("my_folder", { recursive: false }));
console.log(filesInFolder);

// Example of more sophisticated search:
// Find all `.js` files in the folder tree, with modify date newer than 2020-05-01
const borderDate = new Date("2020-05-01")
const found = jetpack.find("foo", {
  matching: "*.js",
  filter: (file) => {
    return file.modifyTime > borderDate
  }
});
console.log(found);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jonrsharpe
Solution 2 illegaldisease
Solution 3
Solution 4 Jakub Szwacz