代码之家  ›  专栏  ›  技术社区  ›  Fallenreaper

Dir-walking获取各种文件的abs路径数组

  •  0
  • Fallenreaper  · 技术社区  · 6 年前

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

    信息:作为python开发人员,我通常使用python包,这些包以独立于平台的方式处理这个问题。我的老板想要一些javascript代码来处理这个目标。。。作为一个JS开发人员,我之前说“哦,这很简单。让我们查一下这个节点,因为我从来没有机会用它弄脏我的手。

    我在node中没有看到任何与Dir-Walking相关的东西,也没有看到一种我可以一起破解来创建这样一个东西的方法。

    我在“子进程”、“控制台”、“文件系统”、“操作系统”、“路径”和“进程”中查找。我没有看到任何类似于:

    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*"
    

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

    有没有一个节点模块,我需要它来完成这一点,这是外部的基本模块?

    2 回复  |  直到 6 年前
        1
  •  3
  •   marzelin    6 年前

    我会这样做:

    同步:

    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

        2
  •  0
  •   Fallenreaper    6 年前

    所以,我在查看文件系统模块时注意到了它的功能 读目录

    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]);
        }
    });
    

    您注意到上面的这个是异步的,但是有一个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)
    }
    

    你可以把它加到基本情况下,在那里你可以看到过滤器。。。或者,您可以返回整个集合,然后使用List方法filter对其进行过滤。