文件的同步散列函数

时间:2015-01-14 12:39:26

标签: javascript node.js

我有一个为给定路径生成校验和的函数

function getHash(path) {
     var fs = require('fs');
     var crypto = require('crypto');

     var fd = fs.createReadStream(path);
     var hash = crypto.createHash('sha1');
     hash.setEncoding('hex');

     fd.on('end', function () {
        hash.end();
        // *** Here is my problem ***
        console.log(hash.read()); 
     });

     fd.pipe(hash);
  };

我想调用calcNewHash函数以便它返回哈希,问题是,我还没有找到这个的异步版本,也许有人可以提供帮助。

添加return语句不起作用,因为该函数位于监听器中

后来我想将校验和添加到一个对象,所以我可以将它作为参数提供给它,但是这仍然没有改变它是同步的......

2 个答案:

答案 0 :(得分:5)

你基本上有2个解决方案:

#1使用promises(即q - npm install q --save)

function getHash(path) {
     var Q = require('q');
     var fs = require('fs');
     var crypto = require('crypto');

     var deferred = Q.defer();

     var fd = fs.createReadStream(path);
     var hash = crypto.createHash('sha1');
     hash.setEncoding('hex');

     fd.on('end', function () {
        hash.end();
        // *** Here is my problem ***
        console.log(hash.read()); 
        deferred.resolve(hash.read());
     });

     fd.pipe(hash);

     return deferred.promise;
};

getHash('c:\\')
   .then(function(result) {
     // do something with the hash result
   });

#2或使用回调函数

function getHash(path, cb) {
     var fs = require('fs');
     var crypto = require('crypto');

     var fd = fs.createReadStream(path);
     var hash = crypto.createHash('sha1');
     hash.setEncoding('hex');

     fd.on('end', function () {
        hash.end();
        // *** Here is my problem ***
        console.log(hash.read()); 
        if (cb) {
          cb(null, hash.read());
        }
     });

     fd.pipe(hash);
};

getHash('C:\\', function (error, data) {
   if (!error) { 
      // do something with data
   } 
});

如果你没有在回调函数中进行深度嵌套,我会选择#2选项。

(注意:幕后承诺也使用回调,如果您有深度嵌套,它只是一个更清洁的解决方案)

答案 1 :(得分:0)

我知道这很老了,但当您沿着这些路线搜索内容时,它是排名最高的结果。因此,对于那些希望在此找到解决方案的人,请执行以下操作:(请注意,只有在您知道文件很小的情况下,此方法才能很好地工作。否则,对于较大的文件,请参考Dieterg提供的答案)

const fs = require('fs');
const crypto = require('crypto');

function fileHashSync(filePath){
    var fileData;

    try{ fileData = fs.readFileSync(filePath, 'utf8'); }

    catch(err){
        if(err.code === 'ENOENT') return console.error('File does not exist. Error: ', err);

        return console.error('Error: ', err);
    }

    return crypto.createHash('sha1').update(fileData, 'utf8').digest('hex');
}