【问题标题】:Splitting file stream at second delimiter在第二个分隔符处拆分文件流
【发布时间】:2019-03-19 17:43:09
【问题描述】:

我目前正在尝试流式传输一个文件,它看起来有点像这样:

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);
}

但是我不认为这是最好的方法。有没有更好的方法来一次拆分和传递两行,最好是作为对象还是作为数组?

【问题讨论】:

    标签: javascript node.js file stream pipeline


    【解决方案1】:

    最终使用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);
      });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      相关资源
      最近更新 更多