2

我有一种情况,我需要逐行处理流中的一些数据。问题是事先不知道数据的编码;它可能是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如果(很可能,何时)与编码不匹配,所有其他编码要么破坏数据,要么无法完全解码。相反,使用Uint8ArrayJavaScript 将意味着缓慢且不方便的 Javascript 循环数据只是为了找到换行符。

关于如何在不使用编码的情况下将流分割成行,同时保持编码不可知的任何建议binary

4

1 回答 1

5

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

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

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

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

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

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

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

如果您连续看到两个 0x0A 值,那么您将进入仅复制数据的第二种模式。

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

于 2012-10-16T06:10:24.657 回答