我正在使用一个处理文件的程序,我可以做几件事,比如重命名它们,读取它们的内容等。
今天我初始化它如下:
return new Promise((resolve, reject) => {
glob("path/for/files/**/*", {
nodir: true
}, (error, files) => {
files = files.map((file) => {
// properties like full name, basename, extension, etc.
});
resolve(files);
});
});
因此,我读取特定目录的内容,返回数组中的所有文件,然后使用 Array.map 迭代数组并更改具有属性的对象的路径。
有时我处理 200.000 个文本文件,因此,这正在成为一个问题,因为它消耗了太多的 RAM。
所以,我想用延迟加载的构造函数代替..但我以前从未这样做过......所以我正在寻找帮助之手。
这是我的代码:
class File {
constructor(path) {
this.path = path;
}
extension() {
return path.extname(this.path);
}
// etc
}
所以,我的主要问题是:我应该只返回房产的评估,还是应该更换它?喜欢这个:
extension() {
this.extension = path.extname(this.path);
}
我知道这是一种权衡......我将按CPU使用情况来交换内存。
谢谢。
如果你想减少 RAM 的使用,我建议你为每个路径存储一个额外的元数据文件,如下所示:
-
根据需要将路径保留在内存中或其中一些路径中。
-
将文件属性保存到硬盘驱动器
files.forEach( (file) => {
// collect the properties you want for the file
// ...
var json = { path: file, extension: extension, .. }
// mark the metadata file so you can access it later, for example: put it in the same path with a suffix
var metaFile = path + '_meta.json';
fs.writeFile(metaFile, JSON.stringify(json), (err) => {
if (err) throw err;
});
});
现在所有的元数据都在硬盘上。我相信,通过这种方式,您可以用内存换取磁盘空间和 CPU 调用。
- 如果要获取文件的属性,只需读取并
JSON.parse
其相应的元数据文件。
没有理由用CPU换取空间。只需遍历树并在找到文件时对其进行处理即可。如果先做深度,则走树所需的空间与树的深度成正比。这几乎可以肯定与在现有代码中创建路径列表具有相同的开销。
对于目录遍历,node.js FAQ 建议使用 node-findit。那里的文档非常清楚。您的代码将如下所示:
var finder = require('findit')(root_directory);
var path = require('path');
var basenames = [];
finder.on('file', function (file, stat) {
basenames.push(path.basename(file));
// etc
}
或者,如果您愿意,可以将捕获的值包装在对象中。
如果仅存储路径属性 NodeJS 类实例,则以字节内存200k * (path.length * 2 + 6)
为例。
如果要对基名、扩展等使用延迟加载,请使用惰性 getter
class File {
constructor(path) {
this.path = path;
this._basename = null;
this._extname = null;
}
get extname() {
return this._extname || (this._extname = path.extname(this.path));
}
get basename() {
return this._basename || (this._basename = path.basename(this.path));
}
}