Может ли Node запускать несколько потоков чтения файлов параллельно? - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь:

  1. получить список путей к файлам
  2. перебрать их и вернуть массив обещаний, которые запускают поток для каждого файла
  3. передать поток в хеш-функцию
  4. передать в сборщик чанков, который разрешает обещание с помощью производного значения хеш-функции при конечном событии

Моя установка прекрасно работает с одним путем и файлом, но снесколько путей и файлов Я получаю ложные результаты.

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

Совместимо ли это с тем, как потоки узлов работают в целом? Кроме того, я уверен, что все, что после первого fs.createReadStream не имеет отношения к проблеме.

const fs = require("fs-extra")
const { Transform } = require("stream")
const hash = require("crypto")
  .createHash("sha256")
  .setEncoding("hex")

module.exports = {
  async start({ filePath }) {
    const hashes = await Promise.all(
      filePath.map(path => {
        return new Promise((resolve, reject) => {
          fs.createReadStream(path)
            .pipe(hash)
            .pipe(
              (() => {
                const data = []
                return new Transform({
                  transform(chunk, encoding, done) {
                    data.push(chunk)
                    done()
                  },
                  flush(done) {
                    resolve(data.toString())
                    done()
                  },
                })
              })()
            )
        })
      })
    )
    console.log(hashes)
  },
}

Ответы [ 3 ]

0 голосов
/ 01 ноября 2019

Для этого вы можете использовать async npm.

async.map(['file1','file2','file3'], fs.stat, function(err, results) {
    // results is now an array of stats for each file
});

async.filter(['file1','file2','file3'], function(filePath, callback) {
  fs.access(filePath, function(err) {
    callback(null, !err)
  });
}, function(err, results) {
    // results now equals an array of the existing files
});

async.parallel([
    function(callback) { ... },
    function(callback) { ... }
], function(err, results) {
    // optional callback
});

async.series([
    function(callback) { ... },
    function(callback) { ... }
]);
0 голосов
/ 01 ноября 2019

Единственное, что не так в вашем примере, это то, что вы создаете только один hash поток. Все файлы будут проходить через один и тот же поток, поэтому все файлы будут содержать одинаковый хэш. В приведенном ниже примере создается новый поток хеш-функции для каждого файла.

const fs = require("fs-extra");
const { Transform } = require("stream");
const hash = require("crypto");

module.exports = {
  async start({ filePath }) {
    const hashes = await Promise.all(
      filePath.map(path => {
        return new Promise((resolve, reject) => {
          fs.createReadStream(path)
            .pipe(hash.createHash("sha256").setEncoding("hex"))
            .pipe(
              (() => {
                const data = [];
                return new Transform({
                  transform(chunk, encoding, done) {
                    data.push(chunk);
                    done();
                  },
                  flush(done) {
                    resolve(data.toString());
                    done();
                  }
                });
              })()
            );
        });
      })
    );
    console.log(hashes);
  }
};
0 голосов
/ 01 ноября 2019

Итак, библиотеки fs и crypto представлены libuv - одной из основных частей nodejs. Эти две библиотеки обеспечивают операции блокировки и запускают их в отдельных потоках. Таким образом, если ваш процессор имеет достаточно ядер для управления большим количеством операций за один раз, вы можете легко запустить множество параллельных процессов. Например, если ваш процессор имеет 2 ядра, вы можете запустить 2 параллельных потока файлов чтения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...