Javascript 从文件系统创建对象树
我需要从CL参数中获取目录的路径,并创建一个对象树,其中包含所选目录的文件结构 如果是文件,则其值应为true。如果它是一个目录,我应该对这个目录做同样的操作,我认为最好的方法是递归 输出应如下所示:Javascript 从文件系统创建对象树,javascript,node.js,object,recursion,filesystems,Javascript,Node.js,Object,Recursion,Filesystems,我需要从CL参数中获取目录的路径,并创建一个对象树,其中包含所选目录的文件结构 如果是文件,则其值应为true。如果它是一个目录,我应该对这个目录做同样的操作,我认为最好的方法是递归 输出应如下所示: { file.txt: true, directory: { one.txt: true, two.txt: true, ... } ... } 到目前为止,我尝试了递归版本,但失败了,不知道为什么。我想这是因为我没有正确处理代码的异步部分。这是我的密码:
{
file.txt: true,
directory: {
one.txt: true,
two.txt: true,
...
}
...
}
到目前为止,我尝试了递归版本,但失败了,不知道为什么。我想这是因为我没有正确处理代码的异步部分。这是我的密码:
const fs = require("fs");
const basePath = process.argv[2]; //Getting the path (it works)
const result = {};
//Function to check my path is exist and it's a directory
const isDirectory = path => {
return new Promise((resolve, reject) => {
fs.lstat(path, (err, stats) => {
if (err) reject("No such file or Directory");
resolve(stats.isDirectory());
});
});
};
//Recursive function that should create the object tree of the file system
const createTree = (path, target) => {
return new Promise((resolve, reject) => {
reject("Promise Oops...");
fs.readdir(path, (err, data) => {
data.forEach(item => {
const currentLocation = `${path}/${item}`;
isDirectory(currentLocation)
.then(isDir => {
if (!isDir) {
target[item] = true;
return;
}
target[item] = {};
resolve(createTree(currentLocation, target[item]));
})
.catch(err => console.log("Oops in then..."));
});
});
});
};
//Consuming the createTree function
(async () => {
try {
const res = await createTree(basePath, result);
console.log(res);
} catch (err) {
console.log("Oops consume...");
}
})();
您可以使用fs.promises而不是基于回调的fs方法,这样可以提高可读性并帮助您轻松发现错误。
您正在记录createTree函数返回的未定义内容。您应该记录结果对象以查看所需的结果
const fs = require("fs");
const basePath = process.argv[2]; //Getting the path (it works)
const result = {};
//Function to check my path is exist and it's a directory
const isDirectory = async (path) => {
try {
const stats = await fs.promises.lstat(path);
return stats.isDirectory();
} catch (error) {
throw new Error("No such file or Directory");
}
};
//Recursive function that should create the object tree of the file system
const createTree = async (path, target) => {
const data = await fs.promises.readdir(path);
for (const item of data) {
const currentLocation = `${path}/${item}`;
const isDir = await isDirectory(currentLocation);
if (!isDir) {
target[item] = true;
continue;
}
target[item] = {};
await createTree(currentLocation, target[item]);
}
};
//Consuming the createTree function
(async () => {
try {
await createTree(basePath, result);
console.log(result);
} catch (error) {
console.log(error.message);
}
})();
您可以使用fs.promises而不是基于回调的fs方法,这样可以提高可读性并帮助您轻松发现错误。
您正在记录createTree函数返回的未定义内容。您应该记录结果对象以查看所需的结果
const fs = require("fs");
const basePath = process.argv[2]; //Getting the path (it works)
const result = {};
//Function to check my path is exist and it's a directory
const isDirectory = async (path) => {
try {
const stats = await fs.promises.lstat(path);
return stats.isDirectory();
} catch (error) {
throw new Error("No such file or Directory");
}
};
//Recursive function that should create the object tree of the file system
const createTree = async (path, target) => {
const data = await fs.promises.readdir(path);
for (const item of data) {
const currentLocation = `${path}/${item}`;
const isDir = await isDirectory(currentLocation);
if (!isDir) {
target[item] = true;
continue;
}
target[item] = {};
await createTree(currentLocation, target[item]);
}
};
//Consuming the createTree function
(async () => {
try {
await createTree(basePath, result);
console.log(result);
} catch (error) {
console.log(error.message);
}
})();
财政司司长/承诺和财政司司长
这是一个使用节点的快速对象和模块的高效、无阻塞程序。这种方法允许您跳过每个路径上浪费的fs.exist或fs.stat调用-
//main.js
从fs/promises导入{readdir}
从路径导入{join,basename}
异步函数*令牌化路径=。
{yield{dir:path}
对于await readdirpath的常量,{withFileTypes:true}
if dirent.isDirectory
yield*tokenisejoinpath,dirent.name
其他的
产生{file:joinpath,dirent.name}
产生{endDir:path}
}
异步函数parse iter=empty
{const r=[{}]
国际热核实验堆的等待常数
如果e.dir
r、 取消移位{}
否则,如果是e.file
r[0][basenamee.file]=true
否则,如果e.endDir
r[1][basenamee.endDir]=r.shift
返回r[0]
}
异步函数*空{}
现在createTree只是令牌化和解析的组合-
const createTree=路径=。=>
解析令牌路径
创建树。
.thenr=>console.logJSON.stringifyr,null,2
.catchconsole.error
让我们获取一些示例文件,这样我们就可以看到它在工作-
$THEAN添加不可变的示例包
$node main.js
{
.: {
main.js:没错,
节点单元模块:{
.纱线完整性:正确,
不变的:{
许可证:是的,
是的,
承包商:{
光标:{
是的,
__测试:{
Cursor.ts.skip:true
},
索引d.ts:正确,
index.js:true
}
},
地区:{
immutable-nonambient.d.ts:true,
不可变的d.ts:正确,
immutable.es.js:true,
immutable.js:true,
immutable.js.flow:true,
immutable.min.js:true
},
package.json:true
}
},
package.json:true,
洛克:没错
}
}
我希望你喜欢读这篇文章。有关使用异步生成器的附加说明和其他方法,请参阅。fs/promises和fs.Dirent
这是一个使用节点的快速对象和模块的高效、无阻塞程序。这种方法允许您跳过每个路径上浪费的fs.exist或fs.stat调用-
//main.js
从fs/promises导入{readdir}
从路径导入{join,basename}
异步函数*令牌化路径=。
{yield{dir:path}
对于await readdirpath的常量,{withFileTypes:true}
if dirent.isDirectory
yield*tokenisejoinpath,dirent.name
其他的
产生{file:joinpath,dirent.name}
产生{endDir:path}
}
异步函数parse iter=empty
{const r=[{}]
国际热核实验堆的等待常数
如果e.dir
r、 取消移位{}
否则,如果是e.file
r[0][basenamee.file]=true
否则,如果e.endDir
r[1][basenamee.endDir]=r.shift
返回r[0]
}
异步函数*空{}
现在createTree只是令牌化和解析的组合-
const createTree=路径=。=>
解析令牌路径
创建树。
.thenr=>console.logJSON.stringifyr,null,2
.catchconsole.error
让我们获取一些示例文件,这样我们就可以看到它在工作-
$THEAN添加不可变的示例包
$node main.js
{
.: {
main.js:没错,
节点单元模块:{
.纱线完整性:正确,
不变的:{
许可证:是的,
是的,
承包商:{
光标:{
是的,
__测试:{
Cursor.ts.skip:true
},
索引d.ts:正确,
index.js:true
}
},
地区:{
immutable-nonambient.d.ts:true,
不可变的d.ts:正确,
immutable.es.js:true,
immutable.js:true,
immutable.js.flow:true,
immutable.min.js:true
},
package.json:true
}
},
package.json:true,
洛克:没错
}
}
我希望你喜欢读这篇文章。增加
解释和其他使用异步生成器的方法,请参阅。谢谢,但它仅适用于一个目录,它将进入第一个目录并退出函数。谢谢,但它仅适用于一个目录,它将进入第一个目录并退出函数。