仅使用NodeJS递归列出路径中的目录

hlswsv35  于 2023-03-07  发布在  Node.js
关注(0)|答案(2)|浏览(113)

我试图用一种优雅的方式来递归地列出所有目录和目录下的文件。我想列出每个目录/子目录下的文件,这样它们就可以区分开了。而且目录路径必须由用户提供。我的努力如下:代码是完全可复制的,但我不断得到空目录,文件被多次列出。有什么更好的方法可以完成这里的列表?

//server.js
"use strict";
const fs = require("fs");
const rlp = require("readline");
const path = require("path");
const filesReadService = require("./filesReadService");
const handleFolders = require("./handleFolders");
//   var basePath = "C:\\Users\\My Computer\\Videos\\Captures";
const rl = rlp.createInterface({
  input: process.stdin,
  output: process.stdout
});

function directoryInput() {
  return new Promise((resolve, reject) => {
    rl.question("Please enter a valid directory: ", input => resolve(input));
  });
}

directoryInput().then(async userInput => {
  rl.close();
  let filesAndFolders = await handleFolders(userInput);
  await filesReadService(userInput, filesAndFolders);
});

...

//handleFolders.js
const fs = require("fs");

const handleFolders = (directory, isRecursive) => {
  return new Promise((resolve, reject) => {
    fs.readdir(directory, (err, files) => {
      if (err) {
        reject(err);
        return;
      }
      resolve(files);
    });
  });
};

module.exports = handleFolders;

...

//filesReadService.js
"use strict";
const fs = require("fs");
const path = require("path");
const handleFolders = require("./handleFolders");

const filesReadService = async (directoryPath, files) => {
  let fullPath;
  let obj = {};
  var promises = files.map(file => {
    fullPath = path.join(directoryPath, file);
    return new Promise((resolve, reject) => {
      fs.stat(fullPath, (err, stat) => {
        if (err) {
          reject(err);
          return;
        }
        if (stat.isFile()) {
          obj = {
            file,
            isFile: true
          };
        } else if (stat.isDirectory()) {
          obj = {
            file,
            isFolder: true
          };
        }

        resolve(obj);
      });
    });
  });

  Promise.all(promises).then(
    values => {
      console.log("The files in this directory:");
      values
        .filter(value => value.isFile)
        .forEach(value => console.log(value.file));
      console.log("\nThe folders in this directory:");

      values
        .filter(value => value.isFolder === true)
        .forEach(async value => {
          let folderPath = path.join(directoryPath, value.file);
          let foldersAndFiles = await handleFolders(folderPath, true);
          console.log(value.file, ":\t", foldersAndFiles);
          await filesReadService(folderPath, foldersAndFiles);
        });
    },
    err => {
      console.log(err);
    }
  );
};

module.exports = filesReadService;
oymdgrw7

oymdgrw71#

const fs = require("fs"), path = require("path");
function recursivelyListDir(dir, callback) {
  fs.readdirSync(dir).forEach(f => {
    let dirPath = path.join(dir, f);
    let isDirectory = fs.statSync(dirPath).isDirectory();
    isDirectory
      ? recursivelyListDir(dirPath, callback)
      : callback(path.join(dir, f));
  });
}

// Function Usage.

recursivelyListDir(__dirname, function(filePath) {
  const fileContents = fs.readFileSync(filePath, "utf8");
  console.log(filePath);
});
z8dt9xmd

z8dt9xmd2#

从节点10.10.0开始,readdir()readdirSync()有一个withFileTypes选项,该选项将导致它返回一个DirEnt数组,这样就不需要调用statSync()
@noor的例子可以简化为如下形式:

function readdirRecursiveSync(dir) {
    const dirs = fs.readdirSync(dir, { withFileTypes: true });
    return dirs.reduce((acc, file) => {
        const filePath = path.join(dir, file.name);
        return acc.concat(
            file.isDirectory() ? readdirRecursiveSync(filePath) : filePath
        );
    }, []);
}

或者,如果要选择性地包括目录:

function readdirRecursiveSync(dir, includeDirs) {
    const dirs = fs.readdirSync(dir, { withFileTypes: true });
    return dirs.reduce((acc, file) => {
        const filePath = path.join(dir, file.name);
        return acc.concat(
            file.isDirectory() ? readdirRecursiveSync(filePath, includeDirs) : [],
            !file.isDirectory() || includeDirs ? filePath : []
        );
    }, []);
}

相关问题