Как написать один файл при чтении из нескольких входных потоков в NodeJS - PullRequest
1 голос
/ 06 октября 2019

Как написать один файл при чтении из нескольких входных потоков одного и того же файла из разных мест с NodeJS.

Поскольку это все еще не ясно Может быть?

Я хочу использовать более высокую производительность для загрузки, скажем, у нас есть 2 местоположения для одного и того же файла, каждое из которых может выполнять только 10 Мб в нисходящем потоке, поэтому я хочу скачатьчасть от первого местоположения и secund параллельно. чтобы получить его с 20 МБ.

, поэтому оба потока должны быть как-то объединены, и оба потока должны знать диапазон, который они загружают.

У меня есть 2 примера

var http = require('http')
var fs = require('fs')

// will write to disk __dirname/file1.zip
function writeFile(fileStream){
  //...
}
// This example assums downloading from 2 http locations
http.request('http://location1/file1.zip').pipe(writeFile)
http.request('http://location2/file1.zip').pipe(writeFile)
var fs = require('fs')

// will write to disk __dirname/file1.zip
function writeFile(fileStream){
  //...
}

// this example is reading the same file from 2 diffrent disks
fs.readfFile('/mount/volume1/file1.zip').pipe(writeFile)
fs.readfFile('/mount/volume2/file1.zip').pipe(writeFile)

Как мне кажется, что это будет работать

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

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

Пытаясь ответить на этот вопрос, я

Мы можем попытаться просто оптимистично поднять Чтение

let SIZE = 64; // 64 byte intervals
let buffers = []
let bytesRead = 0  

function readParallel(filepath,callback){
fs.open(filepath, 'r', function(err, fd) {
  fs.fstat(fd, function(err, stats) {
    let bufferSize = stats.size;


    while (bytesRead < bufferSize) {
      let size = Math.min(SIZE, bufferSize - bytesRead);
      let buffer = new Buffer(size),
      let position = bytesRead
      let length = size
      let offset = bytesRead


      let read = fs.readSync(fd, buffer, offset, length, position);
      buffers.push(buffer);  
      bytesRead += read;
    }

  });
});
}
// At the End: buffers.concat() ==== "File Content"

fs.createReadStream () имеет опцию, которую вы можете передатьчтобы указать начало

let f = fs.createReadStream("myfile.txt", {start: 1000});

Вы также можете открыть нормальный дескриптор файла с помощью fs.open(), затем fs.read() на один байт от позиции прямо перед тем местом, где вы хотите стреаm для позиционирования с использованием аргумента position в fs.read(), а затем вы можете передать этот файловый дескриптор в fs.createReadStream() в качестве опции, и поток начнется с этого файлового дескриптора и позиции (хотя, очевидно, опция start для fs.createReadStream()немного проще).

1 Ответ

0 голосов
/ 07 октября 2019

Использование csv-parse с csv-stringify из CSV Project .

const fs = require('fs');
const parse = require('csv-parse');
const stringify = require('csv-stringify')

const stringifier = stringify();
const writeFile = fs.createWriteStream('out.csv');

fs.createReadStream('file1.csv').pipe(parse()).pipe(stringifier).pipe(writeFile);
fs.createReadStream('file2.csv').pipe(parse()).pipe(stringifier).pipe(writeFile);

Здесь я анализирую каждый файл отдельно (используя разные потоки parse для каждого источника),затем направьте оба к одному и тому же потоку stringify, который объединяет их, затем запишите в место назначения.

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