删除 NodeJs Stream 填充
Remove NodeJs Stream padding
我正在编写一个应用程序,我需要从流中删除前 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 个字节。我怀疑这可能不可能,但我相信一定有办法解决这个问题,所以如果您对此有任何建议,我将不胜感激!
您可以创建一个新的 Transform 流来执行您想要的操作。至于丢失最后 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);
我正在编写一个应用程序,我需要从流中删除前 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 个字节。我怀疑这可能不可能,但我相信一定有办法解决这个问题,所以如果您对此有任何建议,我将不胜感激!
您可以创建一个新的 Transform 流来执行您想要的操作。至于丢失最后 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);