【发布时间】:2015-06-15 08:43:23
【问题描述】:
用户将文件上传到我的快速应用程序中。我需要计算上传文件的哈希值,然后使用计算的哈希值作为文件名将文件写入磁盘。我尝试使用以下代码:
function storeFileStream(file, next) {
createFileHash(file, function(err, hash) {
if (err) {
return next(err);
}
var fileName = path.join(config.storagePath, hash),
stream = fs.createWriteStream(fileName);
stream.on('error', function(err) {
return next(err);
});
stream.on('finish', function() {
return next();
});
file.pipe(stream);
});
}
function createFileHash(file, next) {
var hash = crypto.createHash('sha1');
hash.setEncoding('hex');
file.on('error', function(err) {
return next(err);
});
file.on('end', function(data) {
hash.end();
return next(null, hash.read());
});
file.pipe(hash);
}
问题是我计算文件哈希后写入的文件大小为0。解决此任务的最佳方法是什么?
更新 根据@poke 的建议,我尝试复制我的流。现在我的代码是:
function storeFileStream(file, next) {
var s1 = new pass;
var s2 = new pass;
file.pipe(s1);
file.pipe(s2);
createFileHash(s1, function(err, hash) {
if (err) {
return next(err);
}
var fileName = path.join(config.storagePath, hash),
stream = fs.createWriteStream(fileName);
stream.on('error', function(err) {
return next(err);
});
stream.on('finish', function() {
return next();
});
s2.pipe(stream);
});
}
function createFileHash(file, next) {
var hash = crypto.createHash('sha1');
hash.setEncoding('hex');
file.on('error', function(err) {
return next(err);
});
file.on('end', function(data) {
hash.end();
return next(null, hash.read());
});
file.pipe(hash);
}
这段代码的问题是没有发出事件end 和finish。如果我评论 file.pipe(s2); 会发出事件,但我又遇到了起源问题。
【问题讨论】:
-
由于您将文件 stream 通过管道传输到散列函数中,因此当您拥有散列并且想要写入文件时,您已经完全耗尽了流。您可以先将文件写入磁盘,然后再次读取以计算哈希,或者您需要预先复制您的流;见this question。
-
@poke 谢谢你的评论。第一个选项对我不利,因为我需要先计算哈希。我尝试使用 PassThrough 流复制流并使用 PassThrough 实例而不是
file参数。但是,现在不会发出“完成”和“结束”事件。