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

lan*_*nzz 2 stream node.js

我有一种情况,我需要逐行处理流中的一些数据.问题是数据的编码事先不知道; 它可能是UTF-8或任何遗留单字节编码(例如Latin1,ISO-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);
}
Run Code Online (Sandbox Code Playgroud)

它完成了这项工作,但问题是binary编码被弃用了,将来可能会消失,让我没有那个选项.Buffer如果(很可能,何时)它与编码不匹配,所有其他编码将破坏数据或完全解码它.与合作Uint8Array,而不是将意味着缓慢和不方便的Javascript遍历数据只是为了找到一个换行符.

有关如何动态地将流拆分为行的任何建议,同时保持编码不可而不使用binary编码?

Jon*_*eet 5

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

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

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

我知道它的文本真的,但没有任何编码信息,对数据强加任何形式的解释是危险的.

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

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

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

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

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