Разделение файлового потока на второй разделитель - PullRequest
0 голосов
/ 15 октября 2018

Я сейчас пытаюсь передать файл, который выглядит примерно так:

Header
Title
Header
Title
...

То, как я его обрабатываю, происходит с потоком как таковым:

fs.createReadStream(filePath, streamOpts)
  .pipe(split())
  .on('data', parseLine(data) => ...);

Однако это разбивает файл на каждую строку, поэтому data - это всего лишь одна строка следующей строки.Например,

parseLine(line) => { console.log(data); } 
> "Header"

Я хочу разделить его и каким-то образом заменить data на объект, например,

> "{ header: 'Header', title: 'Title' }"

Есть ли способ сделать это?Я думаю, что это потребовало бы получить две строки вместо одной во время pipe, но я не могу понять, как.


Моя текущая методология следующая:

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

var isHeaderLine = true;
var currentItem = {};
var items = [];

// Read the line from the stream
function parseFileLine(line) {
  if (isHeaderLine) {
    currentItem.header = line 
  } else {
    currentItem.title = line
    items.push(currentItem);
  }
} 

// Read the file as a stream
// Break it into processable lines
function parseFileLines(filePath) {
  const streamOpts = {
    encoding: 'utf8',
  };

  fs.createReadStream(filePath, streamOpts)
    .pipe(split())
    .on('data', parseLine);
}

Однако я не чувствую, что это лучший способ сделать это.Есть ли лучший способ разделить и передать две строки одновременно, предпочтительно в виде объекта или в виде массива?

1 Ответ

0 голосов
/ 16 октября 2018

Закончилось решение этой проблемы с помощью Transform:

function bufferSplitOnce(buffer, splitBuffer, nth) {
  const splitIdx = buffer.indexOf(buffer, splitBuffer, nth);

  return (splitIdx === -1)
    ? [buffer]
    : [buffer.slice(0, splitIdx), buffer.slice(splitIdx + 1)];
}

function bufferSplitN(buffer, splitBuffer, n) {
  const result = [buffer];
  let currentItem;

  for (let i = 0; i < n; i += 1) {
    result.push(...bufferSplitOnce(result.pop(), splitBuffer));
  }

  return result;
}


const streamToEntry = new Transform({
  transform(chunk, encoding, callback) {
    let chunkTail = chunk;

    while (chunkTail) {
      const splitChunk = bufferSplitN(chunkTail, '\n', 2);

      this.push({
        code: splitChunk[0],
        value: splitChunk[1],
      });

      // eslint-disable-next-line prefer-destructuring
      chunkTail = splitChunk[2];
    }
    callback();
  },
  readableObjectMode: true,
  writableObjectMode: true,
});

fs.createReadStream(filePath, streamOpts)
  .pipe(streamToEntry)
  .on('data', (chunk) => {
    console.log(chunk);
  });
...