从文件系统创建对象树
Create object tree from file system
我需要从 CL 参数中获取目录路径并创建一个对象树,其中包含所选目录的文件结构。
如果它是一个文件,它的值应该是真实的。如果它是一个目录,我应该对该目录执行相同的操作(我认为最好的方法是递归)。
输出应该如下所示:
{
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
函数返回的内容。您应该记录 result
对象以查看您想要的结果。
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.Dirent
这是一个使用 Node 的快速 fs.Dirent objects and fs/promises 模块的高效 non-blocking 程序。这种方法允许您跳过每条路径上浪费的 fs.exist
或 fs.stat
调用 -
// main.js
import { readdir } from "fs/promises"
import { join, basename } from "path"
async function* tokenise (path = ".")
{ yield { dir: path }
for (const dirent of await readdir(path, { withFileTypes: true }))
if (dirent.isDirectory())
yield* tokenise(join(path, dirent.name))
else
yield { file: join(path, dirent.name) }
yield { endDir: path }
}
async function parse (iter = empty())
{ const r = [{}]
for await (const e of iter)
if (e.dir)
r.unshift({})
else if (e.file)
r[0][basename(e.file)] = true
else if (e.endDir)
r[1][basename(e.endDir)] = r.shift()
return r[0]
}
async function* empty () {}
现在createTree
只是tokenise
和parse
的组合-
const createTree = (path = ".") =>
parse(tokenise(path))
createTree(".")
.then(r => console.log(JSON.stringify(r, null, 2)))
.catch(console.error)
让我们获取一些示例文件,以便我们可以看到它正在运行 -
$ yarn add immutable # (just some example package)
$ node main.js
{
".": {
"main.js": true,
"node_modules": {
".yarn-integrity": true,
"immutable": {
"LICENSE": true,
"README.md": true,
"contrib": {
"cursor": {
"README.md": true,
"__tests__": {
"Cursor.ts.skip": true
},
"index.d.ts": true,
"index.js": true
}
},
"dist": {
"immutable-nonambient.d.ts": true,
"immutable.d.ts": true,
"immutable.es.js": true,
"immutable.js": true,
"immutable.js.flow": true,
"immutable.min.js": true
},
"package.json": true
}
},
"package.json": true,
"yarn.lock": true
}
}
希望您喜欢这篇文章post。有关使用异步生成器的更多说明和其他方法,请参阅 。
我需要从 CL 参数中获取目录路径并创建一个对象树,其中包含所选目录的文件结构。
如果它是一个文件,它的值应该是真实的。如果它是一个目录,我应该对该目录执行相同的操作(我认为最好的方法是递归)。
输出应该如下所示:
{
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
函数返回的内容。您应该记录 result
对象以查看您想要的结果。
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.Dirent
这是一个使用 Node 的快速 fs.Dirent objects and fs/promises 模块的高效 non-blocking 程序。这种方法允许您跳过每条路径上浪费的 fs.exist
或 fs.stat
调用 -
// main.js
import { readdir } from "fs/promises"
import { join, basename } from "path"
async function* tokenise (path = ".")
{ yield { dir: path }
for (const dirent of await readdir(path, { withFileTypes: true }))
if (dirent.isDirectory())
yield* tokenise(join(path, dirent.name))
else
yield { file: join(path, dirent.name) }
yield { endDir: path }
}
async function parse (iter = empty())
{ const r = [{}]
for await (const e of iter)
if (e.dir)
r.unshift({})
else if (e.file)
r[0][basename(e.file)] = true
else if (e.endDir)
r[1][basename(e.endDir)] = r.shift()
return r[0]
}
async function* empty () {}
现在createTree
只是tokenise
和parse
的组合-
const createTree = (path = ".") =>
parse(tokenise(path))
createTree(".")
.then(r => console.log(JSON.stringify(r, null, 2)))
.catch(console.error)
让我们获取一些示例文件,以便我们可以看到它正在运行 -
$ yarn add immutable # (just some example package)
$ node main.js
{
".": {
"main.js": true,
"node_modules": {
".yarn-integrity": true,
"immutable": {
"LICENSE": true,
"README.md": true,
"contrib": {
"cursor": {
"README.md": true,
"__tests__": {
"Cursor.ts.skip": true
},
"index.d.ts": true,
"index.js": true
}
},
"dist": {
"immutable-nonambient.d.ts": true,
"immutable.d.ts": true,
"immutable.es.js": true,
"immutable.js": true,
"immutable.js.flow": true,
"immutable.min.js": true
},
"package.json": true
}
},
"package.json": true,
"yarn.lock": true
}
}
希望您喜欢这篇文章post。有关使用异步生成器的更多说明和其他方法,请参阅