无缓冲读取的用例

Use-cases for unbuffered reads

我正在为 Ruby 开发一套新的 IO 类(将用作内置核心 IO 类 的替代品)。

在执行此清理 sheet 重新设计时,我遇到了有关缓冲与非缓冲读取 IO 的问题。缓冲 IO 具有减少系统调用数量的优势,并且在尝试读取和解析 UTF-8 时特别有用,其中 char 的长度可能在 1 到 4 个字节之间。我可以提前读取 4k,解析我的编码字符串,并且可以通过 seek 修改文件指针来放回未使用的字节。

但是,对于从管道或套接字之类的流中读取,此选择不存在,因为不允许查找。一旦我阅读了这些字节,我就无法将它们放回去。

所以现在我不得不一次读取 1(到 4)个字节来完成一个可以强制编码为 UTF-8 的字节字符串。如果我尝试进行更大的读取,我会提高我的字符串编码性能,但现在留下未使用的字节。任何未使用的字节(即我读得太远)都需要 "put back" 或 "unget" 通过将它们存储在我的 IO 对象中,但是现在我回到 requiring缓冲 IO.

所以,我想知道我是否让这个决定变得比需要的更复杂。如果无缓冲 IO 没有好的用例,那么我的路径很明确。如果无缓冲IO有很好的理由,我的路径也很清楚。

有没有人有一个或多个无缓冲读取的真实世界用例?

经过深思熟虑,我认为没有需要无缓冲读取的引人注目的用例。因此,我的 IO 类 将默认缓冲读取并尝试满足来自该缓存的读取请求。对于 Block 和 Stream 对象都是如此。

然而,一个有趣的细节出现了。读取缓存可能为 32k 左右。有时用户会尝试阅读超过该大小的内容。在那种情况下,缓存会检测到大读取,使自身失效,然后将读取请求传递给 __read__ "primitive" 进行无缓冲读取。通过选择使半私有 read 作为 API 的一部分可用,用户可以完全绕过读取缓存并直接进行无缓冲读取。

因此,我将提供两全其美的服务,而不会弄乱 API。