处理大容量读操作

Handling large size of Read operation

我正在用我自己的 read 实现插入读取操作,打印一些日志并调用 libc read。我想知道用巨大的 nbyte 参数处理 read 的正确方法应该是什么。由于 nbytesize_t,处理超出范围的读取请求的正确方法是什么?来自 read 联机帮助页:

If the value of nbyte is greater than {SSIZE_MAX}, the result is implementation-defined

这是什么意思,如果我必须处理大量读取请求,我应该怎么办?

您可以将一个大的请求分解成几个较小的请求。

此外,SSIZE_MAX 确实很大。您确定要一次性读取 >2GB 的数据吗?

您可以简单地使用 strace(1) 获取您的 read 系统调用的一些日志。

实际上,读取计数是某个缓冲区(在内存中)的大小,因此超过十几兆字节是非常不寻常的。它通常是几千字节。

所以我相信你不应该关心SSIZE_MAX现实生活中的限制

不要更改 read() 调用的行为 - 只需包装 OS 提供的调用并允许它做它做的事。

ssize_t read( int fd, void *buf, size_t bytes )
{
    ssize_t result;
        .
        .
        .
    result = read_read( fd, buf, bytes );
       .
       .
       .
    return( result );
}

如果您正在实现一个 64 位库,如果调用者向您传递一个大于 SSIZE_MAXsize_t 值,您可能会怎么做?无论如何,你不能把它分成任何合理的东西。

如果您正在实施 32 位库,如果您确实拆分了读取,您将如何传回正确的结果?

read的最后一个参数是缓冲区大小。这不是要读取的字节数。

所以:

  • 如果您收到的缓冲区大小小于 SSIZE_MAX,请使用缓冲区大小调用系统调用 'read'。
  • 如果您收到的缓冲区大小大于 SSIZE_MAX、'read' SSIZE_MAX
  • 如果读取系统调用return-1,return-1也是
  • 如果读取系统调用return 0 或小于SSIZE_MAX --> return 读取的字节总和。
  • 如果读取调用 return 恰好 SSIZE_MAX,则减少 SSIZE_MAX
  • 接收的缓冲区大小
  • 并循环(转到 "So")

不要忘记调整缓冲区指针并计算读取的字节总数。

被实现定义意味着没有正确的答案,调用者永远不应该这样做(因为他们不能确定它将如何处理)。鉴于您要插入系统调用,我建议您只断言 (2) 该值在范围内。如果您最终在某处断言失败,请修复调用代码以使其兼容。