处理大尺寸的Read操作

时间:2016-02-02 09:35:03

标签: c libc

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

  

如果nbyte的值大于{SSIZE_MAX},则结果是实现定义的

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

5 个答案:

答案 0 :(得分:2)

你可以将一个大的请求拆分成几个较小的请求。

此外,SSIZE_MAX非常巨大。你真的确定你需要一次性阅读> 2GB的数据吗?

答案 1 :(得分:2)

不要改变read()调用的行为 - 只需封装操作系统提供的调用并允许它执行它的操作。

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

如果您实现的是64位库,调用者会为您传递的size_t值大于SSIZE_MAX,您可能会怎么做?无论如何,你无法将其分解成任何合理的东西。

如果你正在实现一个32位的库,如果你把读取分开了,你会如何传回正确的结果?

答案 2 :(得分:1)

您只需使用strace(1)获取read系统调用的一些日志。

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

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

答案 3 :(得分:1)

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

所以:

  • 如果您收到的缓冲区大小小于SSIZE_MAX,请致电系统调用'阅读'缓冲区大小。
  • 如果您收到的缓冲区大小超过SSIZE_MAX,请阅读' SSIZE_MAX
  • 如果读取系统调用返回-1,则返回-1
  • 如果读取系统调用返回0或小于SSIZE_MAX - >返回读取的字节总和。
  • 如果读取调用返回SSIZE_MAX,则减小接收到的SSIZE_MAX的缓冲区大小
  • and loop(goto" So")

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

答案 4 :(得分:1)

实现定义意味着没有正确答案,并且调用者不应该这样做(因为他们无法确定如何处理)。鉴于您正在插入系统调用,我建议您断言(2)该值在范围内。如果你最终在某个地方失败,请修改调用代码以使其符合要求。