【问题标题】:Use-cases for unbuffered reads无缓冲读取的用例
【发布时间】:2018-06-19 04:08:42
【问题描述】:

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

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

但是,从管道或套接字之类的流中读取时不存在这种选择,因为不允许搜索。读取这些字节后,我无法将它们放回原处。

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

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

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

【问题讨论】:

    标签: ruby utf-8 io buffer


    【解决方案1】:

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

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

    因此,我将提供两全其美的解决方案,而不会弄乱 API。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多