从输入流中提取最后 n 个字节的良好通用技术有哪些

What are good general techniques to extract the last n bytes from a stream of input

提问人:davolfman 提问时间:2/3/2022 最后编辑:davolfman 更新时间:2/3/2022 访问量:63

问:

假设我有一个长度未知的输入字节的二进制流,以可识别的类似 EOF 的条件结尾,那么有哪些算法可以提取最后一个字节,比如 8 个字节,并以与其余输入不同的方式处理它们?假设没有任何很好的实现特定功能,例如寻找到最后,或倒带流或调用tac。假设输入可能大于 RAM,因此完全缓冲将失败。

对于文件或字段的第一个字节,这非常简单:消耗那么多字节并根据需要处理它们。但对于最后一个字节,算法似乎更容易出错。

我过去通过构建一个 2 段循环缓冲区并在确认未达到 EOF 后才处理最旧的段来做到这一点。

while not end of STREAM
    read n bytes from STREAM and place in open segment
        set m to number of bytes actually read
    if end of STREAM
        o = n - m
        process first m bytes normally from older segment
        process last o bytes from older segment specially
        process first m bytes from newer segment specially
    else
        process n bytes from older segment normally
        declare older segment open

这不仅仅是由极端情况组成,它是由极端情况组成的。 有没有其他算法可以更安全地避免实现错误?或者有没有更好的方法来做这个算法?

算法 IO 语言无关

评论

0赞 user3386109 2/3/2022
您可以使用多少内存来解决这个问题?
0赞 davolfman 2/3/2022
假设不足以容纳整个流。一些固定金额。该进程应保持具有包含内存占用的流式处理进程。使用全输出和全输入缓冲器会根据 RAM 的大小限制有用的大小范围。并不是所有的东西都是服务器,甚至是PC。
2赞 user3386109 2/3/2022
一般的想法是填充缓冲区,然后处理缓冲区中的字节,直到 A) 缓冲区只剩下 8 个未使用的字节,或 B) 缓冲区中剩余的字节不足以进行正常处理。此时,将剩余的字节移动到缓冲区的开头,然后重新填充缓冲区。
0赞 davolfman 2/4/2022
因此,与我正在做的事情类似,但使用线性缓冲区和复制而不是分段的循环缓冲区。这是有道理的,摆脱循环缓冲区的额外复杂性会将代码简化为一个问题而不是两个问题。
1赞 user3386109 2/4/2022
是的,没错。需要注意的一点是,缓冲区需要足够大,以便副本不会占处理时间的很大一部分。我将这种技术用于嵌入式系统上的 HTTP 服务器。HTTP 标头由文本行组成,其中既不知道行的长度,也不知道行数。我使用了 1KB 的缓冲区,同时假设平均行约为 40 字节。这样,代码可以处理大约 25 行,然后复制大约 40 个字节并重新填充缓冲区。因此,平均一行大约有 2 个字节的复制开销。

答: 暂无答案