Skip to content

A proposal to add fs.scandir method to FS module #15699

Closed
@mrmlnc

Description

@mrmlnc

Problem

Now any interaction with files and directories in the File System is as follows:

const fs = require('fs');

const entries = fs.readdirSync('path_to_directory');
const stats = entries.map(fs.statSync);  // Unnecessary File System access

const dirs = [];
const files = [];

entries.forEach((entry, index) => {
    if (stats[index].isDirectory()) {
        dirs.push(entry);
    } else {
        files.push(entry);
    }
});

The problem here is that we are call File System a second time due to the fact that we don't know the directory in front of us, or file (or symlink).

But we can reduce twice File System calls by creating fs.scandir method that can return d_name and d_type. This information is returned from uv_dirent_t (scandir) (libuv). For example, this is implemented in the Luvit and pyuv (also use libuv).

Motivation

  • Performance – reduce twice File System calls
  • More consistency with other platforms/languages
  • Should be easy to implement StringObjectd_name + d_type
    • For fs.readdir: return converted Object to String
    • For fs.scandir: return As is
  • Early speed up for node-glob (also for each package that uses fs.readdir for traversing directories) in most cases (need fs.stat when d_type is a DT_UNKNOWN on the old FS)

Proposed solution

Add a methods fs.scandir and fs.scandirSync in a standard Fyle System module.

const fs = require('fs');

const entries = fs.scandirSync('path_to_directory');

const dirs = [];
const files = [];

entries.forEach((entry) => {
    if (entry.type === fs.constants.S_IFDIR) {
        dirs.push(entry);
    } else {
        files.push(entry);
    }
});

Where entries is an array of objects:

  • name {String} – filename (d_name in libuv)
  • type {Number} – fs.constants.S_* (d_type in libuv)

Final words

Now I solved this problem by creating C++ Addon but... But I don't speak C++ or speak but very bad (i try 😅 ) and it requires you compile when you install a package that requires additional manipulation to the end user (like https://github.com/nodejs/node-gyp#on-windows).

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedPRs that are blocked by other issues or PRs.feature requestIssues that request new features to be added to Node.js.fsIssues and PRs related to the fs subsystem / file system.libuvIssues and PRs related to the libuv dependency or the uv binding.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions