2015-09-27 5 views
1

Я могу добиться рекурсивного обхода файлов в каталоге (например, для изучения всех подкаталогов и файлов в каталоге). Для этого я использовал answer из соответствующего сообщения при переполнении стека. Фрагмент, который ниже:Реестрирование файлов хеша NodeJS в каталоге

var fs = require("fs"); 

var tree = function(dir, done) { 
    var results = { 
     "path": dir, 
     "children": [] 
     }; 
    fs.readdir(dir, function(err, list) { 
    if (err) { return done(err); } 
    var pending = list.length; 
    if (!pending) { return done(null, results); } 
    list.forEach(function(file) { 
     fs.stat(dir + '/' + file, function(err, stat) { 
     if (stat && stat.isDirectory()) { 
      tree(dir + '/' + file, function(err, res) { 
      results.children.push(res); 
      if (!--pending){ done(null, results); } 
      }); 
     } else { 
      results.children.push({"path": dir + "/" + file}); 
      if (!--pending) { done(null, results); } 
     } 
     }); 
    }); 
    }); 
}; 

module.exports = tree; 

Когда я бегу:

tree(someDirectoryPath, function(err, results) { 
     if (err) throw err; 

     console.log(results); 
     }); 

я получаю результат выборки, например, это один:

{ path: '/Users/UserName/Desktop/1', 
    children: 
    [ { path: '/Users/UserName/Desktop/1/file1' }, 
    { path: '/Users/UserName/Desktop/1/file2' }, 
    { path: '/Users/UserName/Desktop/1/file3' }, 
    { path: '/Users/UserName/Desktop/1/subdir1', 
     children: [Object] } ] } 

Я также способен хэш один файл в определенном месте, используя модуль Readsream модуля fs. Фрагмент кода для этого ниже:

/** 
* Checking File Integrity 
*/ 
var fs = require('fs'), 
     args = process.argv.splice('2'), 
     path = require('path'), 
     traverse = require('/Users/UserName/Desktop/tree.js'), 
     crypto = require('crypto'); 
//var algorithm = ['md5', 'sha1', 'sha256', 'sha512']; 
var algorithm = 'sha512'; 
var hashTable = new Array(); 

     var hash = crypto.createHash(algorithm); 

     var fileStream = fs.ReadStream(args[0]); 

     fileStream.on('data', function(data) { 
       hash.update(data); 
     fileStream.on('end', function() { 
       var digest = hash.digest('hex'); 
       console.log('algorithm used: ', algorithm); 
       console.log('hash for the file: ',digest); 
       hashTable[args[0]] = digest; 
       console.log(hashTable); 
     }); 
}); 

Где арг [0] хранит расположение файла, который будет прочитан ReadStream. После перемешивания конкретного файла, журнал консоль возвращается следующим образом:

node fileIntegrityChecker.js hello.txt 
algorithm used: sha512 
hash for the file: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 
the hashtable is: [ 'hello.txt': '9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043' ] 

Моя проблема заключается в том, что я пытался каким-то образом интегрировать функциональность модуля дерева в хэш связанных JS файл. Моя идея состоит в том, что программа будет захватывать вход пользователя, как путь к каталогу, и этот ввод будет обработан для перемещения по всем подкаталогам и файлам папки. Кроме того, метод fileStream.on должен быть включен в обратный вызов из древовидного модуля. Однако я не полностью инициирован механизмом обратного вызова, и я надеюсь получить от вас некоторое представление.

Это то, что я пытался

/** 
* Checking File Integrity 
*/ 
var fs = require('fs'), 
     args = process.argv.splice('2'), 
     path = require('path'), 
     tree = require('/Users/UserName/Desktop/tree.js'), 
     crypto = require('crypto'); 
//var algorithm = ['md5', 'sha1', 'sha256', 'sha512']; 
var algorithm = 'sha512'; 
var hashTable = new Array(); 

     var pathString = 'Users/UserName/Desktop/1'; 
     tree(pathString, function(err, results) { 
      if (err) throw err; 

      var hash = crypto.createHash(algorithm); 
      var fileStream = fs.ReadStream(results.children[1]['path']); 
      fileStream.on('data', function(data) { 
       hash.update(data); 
      fileStream.on('end', function() { 
       var digest = hash.digest('hex'); 
       console.log('algorithm used: ', algorithm); 
       console.log('hash for the file: ',digest); 
       hashTable[results.children[1]['path']] = digest; 
       console.log('The hashtable is: ', hashTable); 
       }); 
      }); 
     }); 

Теперь, я сделал некоторый прогресс в том смысле, что я не получаю сообщение об ошибке. В основном я достиг своего масштаба. Однако Я могу извлечь только один результат явно. По какой-то причине я не могу думать, как итеративно (например) получить каждый дочерний объект JSON-результата. Если это будет решено, я думаю, что проблема будет полностью решена.

Не могли бы вы показать мне способ, как успешно объединить модуль и файл js, чтобы рекурсивно пройти все содержимое каталога и создать хэш для каждого файла в нем. Мне нужно это, чтобы в конечном счете проверить, произошли ли некоторые изменения в файлах на основе их хэшей. Спасибо!

+1

обратного вызова выглядит отлично. EISDIR означает, что вы пытаетесь выполнить операцию в каталоге, когда ожидается другой тип файла. Вы проследили, какая строка выдает ошибку? – chriskelly

+0

Линейное дерево (someDirectoryPath, function (err, results) {дает ошибку. Таким образом, это означает, что проблема может возникнуть при передаче переменной someDirectory функции tree(). – v01d

+0

@chriskelly Я внесла некоторые изменения, может пожалуйста, проверьте их? – v01d

ответ

1

Простейшей задачей было бы генерировать хэш, когда вы уже идите по дереву каталогов. Это включает в себя обновление файла tree.js следующим образом:

} else { 
     var fname = dir + "/" + file}; 
     // put your hash generation here 
     generateHash(fname, function (e, hash) { 
     if (e) done(e); 

     results.children.push({"path": fname, "hash" : hash); 
     if (!--pending) { 
      done(null, results); 
     } 
     }); 
    } 

Затем поместите ваш хэш-код генерации в функции, как это:

function generateHash (filename, callback) { 
    var algorithm = 'sha512'; 
    var hashTable = new Array(); 

    var hash = crypto.createHash(algorithm); 
    var fileStream = fs.ReadStream(filename); 

    fileStream.on('data', function(data) { 
     hash.update(data);  
    }); 
    fileStream.on('end', function() { 
     var digest = hash.digest('hex'); 
     callback(null, digest); 
    }); 
} 
+0

Когда я пытаюсь запустить ваш код, появляется следующая ошибка: bin ding.open (pathModule._makeLong (путь), ^ TypeError: путь должен быть строкой. Консоль выдает строку var fileStream = fs.ReadStream (имя файла); – v01d

+0

По-видимому, я получаю утечки памяти. (узел): возможно обнаружение утечки памяти EventEmitter. Добавлены 11 слушателей. Используйте emitter.setMaxListeners(), чтобы увеличить лимит. crypto.js: 126 return this._handle.digest (outputEncoding); ^ Ошибка: не инициализирована при ошибке (родной) на Hash.digest (crypto.js: 126: 23) в ReadStream. (/Users/MacriniciDan/Desktop/tree2.js:17:31) в ReadStream.emit (events.js: 129: 20) at _stream_readable.js: 908: 16 at process._tickCallback (node.js: 355: 11) – v01d

+1

Спасибо! Он работает сейчас. Благодарим вас за все ваши усилия и решение! – v01d

0

Используя vinyl-fs, вы могли бы шарик каталог. Вероятно, это немного сократит ваш код.

Затем вы будете передавать файлы через обработчик, который будет генерировать ваш хэш.

Вот пример:

fs.src(['./**/*.js']) 
    .pipe(hasher) 
    .pipe(concater) 
    .dest('output.file') 
Смежные вопросы