目标:使用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路径的详尽列表。
答案 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);
答案 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在那里进行过滤。