逐行读取流而不知道其编码



我有一种情况,需要逐行处理流中的一些数据。问题是数据的编码不是预先已知的;它可以是UTF-8或任何传统的单字节编码(例如Latin1ISO-8859-5等)。它将不是UTF16或像EBCDIC这样的外来词,所以我可以合理地期望n是明确的,所以理论上我可以把它分成几行。在某个时刻,当我遇到一条空行时,我需要将流的其余部分馈送到其他地方(不将其拆分成行,但仍然没有任何重新编码);想想HTTP风格的头后面跟着一个不透明的主体。

这是我得到的:

function processStream(stream) {
var buffer = '';
function splitLines(data) {
buffer += data;
var lf = buffer.indexOf('n');
while (lf >= 0) {
var line = buffer.substr(0, lf - 1);
buffer = buffer.substr(lf + 1);
this.emit('line', line);
lf = buffer.indexOf('n');
}
}
function processHeader(line) {
if (line.length) {
// do something with the line
} else {
// end of headers, stop splitting lines and start processing the body
this
.removeListener('data', splitLines)
.removeAllListeners('line')
.on('data', processBody);
if (buffer.length) {
// process leftover buffer as part of the body
processBody(buffer);
buffer = '';
}
}
}
function processBody(data) {
// do something with the body chunks
}
stream.setEncoding('binary');
stream
.on('data', splitLines)
.on('line', processHeader);
}

它完成了这项工作,但问题是binary编码已被弃用,将来可能会消失,让我没有这个选项。如果(很可能是在什么时候)数据与编码不匹配,所有其他Buffer编码要么会损坏数据,要么无法完全解码。相反,使用Uint8Array将意味着Javascript在数据上循环以查找换行符的速度缓慢且不方便。

关于如何在不使用binary编码的情况下保持编码不可知性的同时,将流动态拆分为行,有什么建议吗?

免责声明:我不是Javascript开发人员。

在某个时候,当我遇到空行时,我需要将流的其余部分馈送到其他地方(不将其拆分成行,但仍然没有任何重新编码)

右。在这种情况下,听起来你真的根本不想把数据看作文本。像对待任何二进制数据一样对待它,并将其拆分为字节0x0A。(请注意,如果它从Windows开始,可能也想删除任何尾随的0x0D值。)

我知道这确实是文本,但如果没有任何编码信息,对数据进行任何解释都是危险的。

所以你应该保留两个状态:

  • 字节数组列表
  • 当前缓冲区

当您接收到数据时,您在逻辑上希望创建一个新的数组,其中当前缓冲区在准备新数据。(为了提高效率,您可能不想实际创建这样的数组,但我会从一开始就这样做,直到它工作为止。)查找任何0x0A字节,并相应地拆分数组(创建一个新的字节数组作为现有数组的"切片",并将切片添加到列表中)。新的"当前缓冲区"将是您在最终0x0A之后剩下的任何数据。

如果您在一行中看到两个0x0A值,那么您将进入只复制数据的第二种模式。

这一切都是假设Javascript/Node组合允许您将二进制数据作为二进制数据进行操作,但如果没有,我会感到震惊。重要的一点是而不是在任何时候将其解释为文本。

相关内容

  • 没有找到相关文章

最新更新