【问题标题】:Remove NodeJs Stream padding删除 NodeJs 流填充
【发布时间】:2017-04-11 18:51:37
【问题描述】:

我正在编写一个应用程序,我需要从流中删除第一个 X 和最后一个 Y 字节。所以我需要的基本上是一个可以传递给pipe 的函数,它将X 和Y 作为参数,并在流通过时从流中删除所需的字节数。我的简化设置是这样的:

const rs = fs.createReadStream('some_file')
const ws = fs.createWriteStream('some_other_file')
rs.pipe(streamPadding(128, 512)).pipe(ws)

之后,some_other_file应该包含some_file的所有内容减去前128个字节和后512个字节。我已经阅读了有关流的内容,但无法弄清楚如何正确执行此操作,以便它还可以处理传输期间的错误并正确执行背压。

据我所知,我需要一个双工流,每当我从它读取数据时,就从它的输入流中读取数据,跟踪我们在流中的位置,并在发出数据之前跳过前 128 个字节。一些关于如何实施的提示将非常有帮助。

第二部分似乎更难,如果不是不可能的话,因为在输入流实际关闭之前,我怎么知道我是否已经达到最后 512 个字节。我怀疑这可能是不可能的,但我相信一定有办法解决这个问题,所以如果您对此有任何建议,我将非常感激!

【问题讨论】:

    标签: node.js stream duplex


    【解决方案1】:

    您可以创建一个新的Transform Stream 来满足您的需求。至于丢失最后的x 字节,您可以始终保持最后的x 字节缓冲,并在流结束时忽略它们。

    类似这样的事情(假设您正在使用缓冲区)。

    
    const {Transform} = require('stream');
    
    
    const ignoreFirst = 128,
          ignoreLast = 512;
    
    let lastBuff,
        cnt = 0;
    
    const MyTrimmer = new Transform({
      transform(chunk,encoding,callback) {
        let len = Buffer.byteLength(chunk);
    
        // If we haven't ignored the first bit yet, make sure we do
        if(cnt <= ignoreFirst) {
          let diff = ignoreFirst - cnt;
    
          // If we have more than we want to ignore, adjust pointer
          if(len > diff)
            chunk = chunk.slice(diff,len);
          // Otherwise unset chunk for later
          else
            chunk = undefined;
        }
    
        // Keep track of how many bytes we've seen
        cnt += len;
    
        // If we have nothing to push after trimming, just get out
        if(!chunk)
          return callback();
    
        // If we already have a saved buff, concat it with the chunk
        if(lastBuff)
          chunk = Buffer.concat([lastBuff,chunk]);
        
        // Get the new chunk length
        len = Buffer.byteLength(chunk);
        
        // If the length is less than what we ignore at the end, save it and get out
        if(len < ignoreLast) {
          lastBuff = chunk;
          return callback();
        }
    
        // Otherwise save the piece we might want to ignore and push the rest through
        lastBuff = chunk.slice(len-ignoreLast,len);
        this.push(chunk.slice(0,len-ignoreLast));
        callback();
      }
    });
    
    
    

    然后你添加你的管道,假设你正在读取一个文件并写入一个文件:

    const rs = fs.createReadStream('some_file')
    const ws = fs.createWriteStream('some_other_file')
    
    myTrimmer.pipe(ws);
    rs.pipe(myTrimmer);
    

    【讨论】:

      猜你喜欢
      • 2015-04-21
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 2020-10-11
      • 2015-08-20
      • 2021-06-09
      相关资源
      最近更新 更多