我正在构建一个nodewebkit应用程序,它使本地目录与远程FTP保持同步。要在第一次运行应用程序时构建初始索引,我从远程服务器下载包含所有文件及其文件夹的哈希值的索引文件。然后我浏览此列表并在用户的本地文件夹中找到匹配项。
远程/本地文件夹的总大小可以超过10GB。可以想象,扫描10GB的单个文件可能会非常慢,特别是在普通硬盘(不是SSD)上。
节点中是否有一种方法可以有效地获取文件夹的哈希值而无需循环并散列内部的每个文件?这样,如果文件夹哈希不同,我可以选择进行昂贵的单个文件检查(一旦我有一个本地索引与远程文件进行比较,我就是这样做的。)
答案 0 :(得分:1)
您可以迭代地遍历目录,统计目录及其包含的每个文件,而不是跟随链接并生成哈希。这是一个例子:
'use strict';
// npm install siphash
var siphash = require('siphash');
// npm install walk
var walk = require('walk');
var key = siphash.string16_to_key('0123456789ABCDEF');
var walker = walk.walk('/tmp', {followLinks: false});
walker.on('directories', directoryHandler);
walker.on('file', fileHandler);
walker.on('errors', errorsHandler); // plural
walker.on('end', endHandler);
var directories = {};
var directoryHashes = [];
function addRootDirectory(name, stats) {
directories[name] = directories[name] || {
fileStats: []
};
if(stats.file) directories[name].fileStats.push(stats.file);
else if(stats.dir) directories[name].dirStats = stats.dir;
}
function directoryHandler(root, dirStatsArray, next) {
addRootDirectory(root, {dir:dirStatsArray});
next();
}
function fileHandler(root, fileStat, next) {
addRootDirectory(root, {file:fileStat});
next();
}
function errorsHandler(root, nodeStatsArray, next) {
nodeStatsArray.forEach(function (n) {
console.error('[ERROR] ' + n.name);
console.error(n.error.message || (n.error.code + ': ' + n.error.path));
});
next();
}
function endHandler() {
Object.keys(directories).forEach(function (dir) {
var hash = siphash.hash_hex(key, JSON.stringify(dir));
directoryHashes.push({
dir: dir,
hash: hash
});
});
console.log(directoryHashes);
}
您当然希望将其转换为某种命令行应用程序以获取参数,并仔细检查每次都以正确的顺序返回文件(可能在散列之前根据文件名对文件统计信息进行排序!)这样siphash每次都会返回正确的哈希值。
这不是经过测试的代码..只是为了提供一个我可能从这种事情开始的例子。
编辑:并且为了减少依赖性,如果你想要require('crypto');
,你可以使用Node的加密lib而不是siphash,如果你当然喜欢自己走路/统计目录和文件。