dir步行以获取各种文件的abs路径数组

时间:2018-09-20 13:49:32

标签: javascript node.js node-modules

目标:使用NodeJ递归获取目录中所有文件的绝对路径列表。

信息:作为python开发人员,我通常使用python软件包,这些软件包以独立于平台的方式处理此问题。我的老板想要一些能够实现此目标的JavaScript代码...作为以前的JS开发人员,我就像“哦,这很容易。让我们查找该节点,因为我没有机会弄清它。”但我似乎弄错了。

我在节点上看不到任何与Dir Walking有关的东西,也没有发现我可以一起创造这种东西的方式。

我正在寻找“子进程”,“控制台”,“文件系统”,“ OS”,“路径”和“进程”。我没有看到任何可以做的事情类似于:

pushd .
cd $dir
for folder in $(ls);
do
  pushd .
  cd $folder
    //call again
  ls $(pwd)$flag >> $dir/files_matching.txt 
  popd
done;

 // or any platform independent means of recursively getting 
 // all files and their abs path which meet flag criterion, 
 //  such as "*.txt" || "_*found*"

我可以使用子进程来执行命令行项,但是随后我需要根据使用该应用程序的OS创建一堆条件,并认为这已经存在。

我不想重新发明轮子,但认为这已经完成了;我只是在基本模块中看不到它。

是否需要一个在基本模块之外的节点模块来完成此任务?

我试图不必手动滚动基于条件os的系统来获取目录下所有文件(或由于扩展等导致的子集)的abs路径的详尽列表。

2 个答案:

答案 0 :(得分:3)

我会这样:

同步:

const fs = require("fs");
const { resolve } = require("path");

const getFiles = dir => {
  const stack = [resolve(dir)];
  const files = [];
  while (stack.length) {
    dir = stack.pop();
    fs.readdirSync(dir).forEach(item => {
      const path = resolve(dir, item);
      (fs.statSync(path).isDirectory() ? stack : files).push(path);
    });
  }
  return files;
};

console.log(getFiles("."));

异步:

const fs = require("fs");
const { resolve } = require("path");
const pify = require("util").promisify;
const readdir = pify(fs.readdir);
const stat = pify(fs.stat);

const getFiles = async dir => {
  const files = await readdir(resolve(dir));
  const filesP = files.map(async file => {
    const path = resolve(dir, file);
    return (await stat(path)).isDirectory() ? getFiles(path) : path;
  });
  // return (await Promise.all(filesP)).flat(); // flat supported in node ~11
  return [].concat(...(await Promise.all(filesP)));
};

getFiles(".").then(console.log);

异步演示https://repl.it/@marzelin/getFiles

答案 1 :(得分:0)

因此,我正在查看文件系统模块,并注意到函数 readDir

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

可以部分解决问题。我猜它没有命名我想要的方法。我一直在寻找涉及LIST和DIR的内容,而不涉及READ。

无论如何,这是一种读取目录的方法。

var fs = require('fs');

if (process.argv.length <= 2) {
    console.log("Usage: " + __filename + " path/to/directory");
    process.exit(-1);
}

var path = process.argv[2];

fs.readdir(path, function(err, items) {
    console.log(items);

    for (var i=0; i<items.length; i++) {
        console.log(items[i]);
    }
});

您注意到上面的这个是Async,但是有一个Sync变体,只需在签名中添加“ Sync”。现在,您需要确定目录中是否包含某些内容:

let file = fs.statSync("path/to/directory")
let isDir = file.isDirectory()

因此您可以将所有这些结合在一起。

var fs = require('fs')
function recurse_file_system(path, contains) {
  let files = fs.readdirSync(path);
  let dArr = [];
  let fArr = [];
  for (let i in files){
    let newPath = path + "/" + files[i]
    if (fs.statSync(newPath).isDirectory()){
      dArr.push(newPath)
    }else{
      if (filter(files[i], ".txt")){
         fArr.push(newPath)
      }
    }
  }
  if (arr.length == 0){
    return fArr;
  }else{
    for (let d in dArr){
      let rslt = recurse_file_system(dArr[d]);
      for (let i in rslt){
        fArr.push(rslt[i])
      }
    }
    return fArr;
  }
}
console.log("Files:")
console.log(recurse_file_system("/"))

现在,如果要扩展此范围,您要做的就是添加一个过滤器来说,根据特定条件(例如文件名限制)限制返回的大小。

function filter(filename, contains){
   let reg = new RegEx(contains)
   return reg.test(filename)
}

,您可以将其添加到基本情况下,在其中看到过滤器...,也可以只返回WHOLE集并使用List方法filter在那里进行过滤。