我正在使用 Node 14.5 和文件系统 api 进行一些基本的 readdir 操作和文件/目录读取操作...
我只是想知道,当我得到一个描述文件/目录的“Dirent”对象时,当我迭代它的属性时,我可以看到一个带有数值的“[Symbol(type)]”属性,这可能是该文件的类型..但是我无法以任何方式访问该属性...
Dirent {
name: 'Some name of file.mp4',
[Symbol(type)]: 1
}
我现在的问题是:这种财产是什么?我如何访问它?或者我怎样才能创建这样的属性以及为什么它会出现?我知道我可以使用 isDirectory() 等方法,但我只是想知道该属性是什么......
这是我的代码:
const fs = require('fs');
const path = require('path');
const walkDirs = async (dir_path, isSubdir = false, round = 0) => {
try {
const files = await fs.promises.readdir(dir_path);
const dirs = fs.opendirSync(dir_path);
// console.log(dirs);
for await (const dirent of dirs) {
for ( let prop in dirent) {
console.log("prop:", prop, dirent[prop]);
}
}
} catch(error) {
console.log("Error catched: ", error);
}
}
walkDirs("D:/", false, 0);
如果您访问 DirEnt
类的fs 模块源代码,您会发现以下内容:
class Dirent {
constructor(name, type) {
this.name = name;
this[kType] = type;
}
isDirectory() {
return this[kType] === UV_DIRENT_DIR;
}
isFile() {
return this[kType] === UV_DIRENT_FILE;
}
isBlockDevice() {
return this[kType] === UV_DIRENT_BLOCK;
}
isCharacterDevice() {
return this[kType] === UV_DIRENT_CHAR;
}
isSymbolicLink() {
return this[kType] === UV_DIRENT_LINK;
}
isFIFO() {
return this[kType] === UV_DIRENT_FIFO;
}
isSocket() {
return this[kType] === UV_DIRENT_SOCKET;
}
}
如果您随后寻找kType
,您会发现:
const kType = Symbol('type');
并且,该代码中的所有值(例如 UV_DIRECT_DIR
和
UV_DIRENT_FILE
)都是从 libuv 导入的常量,用于描述目录条目的类型。因此,您所询问的属性似乎包含目录条目的 libuv 类型,并且他们使用符号作为属性名称,因为他们不打算公开使用或记录该内部实现细节。
如果你不知道libuv是什么,它是nodejs用来访问操作系统服务的跨平台库。它将一些操作系统细节抽象为一个通用接口,以允许一次编写更多的nodejs代码并在多个平台(Win/Mac/Unix)上工作。
uv.h
中的 libuv 中的 C++ 代码中定义于此处
。
typedef enum {
UV_DIRENT_UNKNOWN,
UV_DIRENT_FILE,
UV_DIRENT_DIR,
UV_DIRENT_LINK,
UV_DIRENT_FIFO,
UV_DIRENT_SOCKET,
UV_DIRENT_CHAR,
UV_DIRENT_BLOCK
} uv_dirent_type_t;
const num = file[Object.getOwnPropertySymbols(file)[0]]
此代码片段演示了如何使用 withFileTypes
符号读取目录,并返回一个对象,其中文件和目录拆分为各自的数组。
const readTypes = {
1: "file",
2: "dir",
3: "link"
}
const readDir = (dir) => new Promise ((resolve, reject) => {
fs.readdir(dir, { withFileTypes: true }, (err, files) => {
if (err) return reject(console.error(err));
const result = {
root: path.resolve(dir),
file: [],
dir: []
};
for (const file of files) {
const num = file[Object.getOwnPropertySymbols(file)[0]]
const validEnum = Object.keys(readTypes).includes(String(num));
if (!validEnum) continue
const type = readTypes[num];
result[type].push(path.resolve(dir, file.name))
}
resolve(result)
})
});
readDir('./').then(console.log)
输出将如下所示:
{
root: '/home/user/repos/create-react-app',
file: [
'/home/user/repos/create-react-app/.alexignore',
'/home/user/repos/create-react-app/.alexrc',
'/home/user/repos/create-react-app/.eslintignore',
'/home/user/repos/create-react-app/.eslintrc.json',
'/home/user/repos/create-react-app/.gitattributes',
'/home/user/repos/create-react-app/.gitignore',
'/home/user/repos/create-react-app/.prettierignore',
'/home/user/repos/create-react-app/.prettierrc',
'/home/user/repos/create-react-app/CHANGELOG-0.x.md',
'/home/user/repos/create-react-app/CHANGELOG-1.x.md',
'/home/user/repos/create-react-app/CHANGELOG-2.x.md',
'/home/user/repos/create-react-app/CHANGELOG-3.x.md',
'/home/user/repos/create-react-app/CHANGELOG-4.x.md',
'/home/user/repos/create-react-app/CHANGELOG.md',
'/home/user/repos/create-react-app/CODE_OF_CONDUCT.md',
'/home/user/repos/create-react-app/CONTRIBUTING.md',
'/home/user/repos/create-react-app/LICENSE',
'/home/user/repos/create-react-app/README.md',
'/home/user/repos/create-react-app/SECURITY.md',
'/home/user/repos/create-react-app/lerna.json',
'/home/user/repos/create-react-app/netlify.toml',
'/home/user/repos/create-react-app/package-lock.json',
'/home/user/repos/create-react-app/package.json',
'/home/user/repos/create-react-app/screencast-error.svg',
'/home/user/repos/create-react-app/screencast.svg',
'/home/user/repos/create-react-app/test.mjs'
],
dir: [
'/home/user/repos/create-react-app/.git',
'/home/user/repos/create-react-app/.github',
'/home/user/repos/create-react-app/docusaurus',
'/home/user/repos/create-react-app/packages',
'/home/user/repos/create-react-app/tasks',
'/home/user/repos/create-react-app/test'
]
}
我希望这可以帮助您回答您的问题,“我如何访问它?”