Как сделать SHA1 из файла в Angular с помощью программы чтения файлов? - PullRequest
1 голос
/ 24 мая 2019

У меня есть элемент ввода на моей html-странице, с помощью которого я могу выбрать 1 / несколько файлов.
После того, как я выбрал свои файлы, я хотел бы прочитать содержимое каждого файла, используяFileReader для создания из него SHA1.
Как только я получу значение SHA1, я бы хотел сохранить его где-нибудь.

Проблема в том, что я получаю значение SHA1 только после .onload в FileReaderзакончен, и это происходит после того, как я пытаюсь сохранить его значение.

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

Это моя угловая функция, которую я вызываю, когда выбираю свои файлы:

hashFiles(files: Array<any>){
    console.log('start hashing');
    for (const file of files) {
      const myHash = hashFile(file);
      console.log('hash: ', myHash);
      /*I would like to save myHash here*/
    }
    console.log('done hashing');
}

Это моя функция javascript, которая вызывается из angular, которая будет читать файлс FileReader, а затем создайте хэш sha1 из его содержимого

function hashFile(fileToHandle) {
  console.log('1');

  var reader = new FileReader();

  console.log('2');

  reader.onload = (function() {

    return function(e) {
      console.log('4');

      const hash = CryptoJS.SHA1(arrayBufferToWordArray(e.target.result)).toString();
      console.log('hash result in fileReader: ', hash);
      return hash;
    };
  }) (fileToHandle);
  reader.onerror = function(e) {
    console.error(e);
  };

  console.log('3');

  reader.readAsArrayBuffer(fileToHandle);

  console.log('5');
}

function arrayBufferToWordArray(ab) {
  var i8a = new Uint8Array(ab);
  var a = [];
  for (var i = 0; i < i8a.length; i += 4) {
    a.push(i8a[i] << 24 | i8a[i + 1] << 16 | i8a[i + 2] << 8 | i8a[i + 3]);
  }
  return CryptoJS.lib.WordArray.create(a, i8a.length);
}

При запуске этого кода у меня в консоли есть следующее:

start hashing
1
2
3
5
hash: undefined
done hashing
4
hash result in fileReader: 327c468b64b4ca54377546f8a214d703ccbad64b

И мне нужно, чтобы оно было:

start hashing
1
2
3
hash result in fileReader: 327c468b64b4ca54377546f8a214d703ccbad64b
4
5
hash: 327c468b64b4ca54377546f8a214d703ccbad64b
done hashing

Вот пример моего кода:
https://stackblitz.com/edit/sha1-from-file

1 Ответ

0 голосов
/ 24 мая 2019

Вам нужно либо работать с обратными вызовами, либо добавить оболочку обещания (также можно наблюдать) к собственным обратным вызовам FileReader.Вот как это можно сделать, просто добавив обратный вызов.

Stackblitz

app.component.ts

hashFiles(event) {
  console.log('start hashing');

  const numberOfFiles = event.target.files.length;
  var fileCounter = 0;
  for (const file of event.target.files) {
    hashFile(file, (hashedFile, hash) => {
    console.log('hash: ', hash);
    fileCounter++;
    if(fileCounter === numberOfFiles)
      console.log('Done Hashing!');
    });
  }
}

script.js

export function hashFile(fileToHandle, callback) {
  var CryptoJS = require("crypto-js");

  console.log('1');

  var reader = new FileReader();

  console.log('2');

  reader.onloadend = (function() {
    return function(e) {
      console.log('4');
      const hash = CryptoJS.SHA1(arrayBufferToWordArray(e.target.result)).toString();
      console.log('hash result in fileReader: ', hash);
      callback(fileToHandle, hash);
    };
  }) (fileToHandle);
  reader.onerror = function(e) {
    console.error(e);
  };

  console.log('3');

  reader.readAsArrayBuffer(fileToHandle);
}
...