read()系统调用实际读取的数据量

时间:2018-05-27 20:56:25

标签: c linux file

假设我有一个文件,其文件描述符在EOF之前有超过n个字节,并且我为n个字节调用read()系统调用。该函数是否保证将n个字节读入缓冲区?或者它可以少读?

3 个答案:

答案 0 :(得分:3)

保证read系统调用可以读取您要求的多个字符,除非它不能。但事实证明,有很多例外 - 很多情况下它无法读取你所要求的那么多字符 - 它基本上最安全的假设任何给定的read调用可能赢了不要读你想要的字符数。我认为总是在编写代码时考虑到这一点是一种好习惯。

我系统上的手册页说

  

如果描述符引用了在文件结尾之前剩余许多字节的普通文件,系统保证读取所请求的字节数,但不是其他情况。

因此,如果它不是普通文件,或者它是普通文件但没有足够的字符,那么你会得到的数量少于你要求的数量。但是,如果您询问,是的,您应该保证获得与您要求的完全一样多的字符。

尽管如此,如果您发现自己可以选择假设read被确保准确读取所请求的字符数,而不是承认它可能会返回更少,我总是会写代码假设它可能会减少回报。也就是说,如果你有一个像

这样的电话
r = read(fd, buf, n);

假设如果r大于0,那么通常不会有太大的好处,它必须正好n。您的代码必须能够处理r < n情况,以便它几乎在文件结束时才能正常运行,因此除非您想要两个不同的代码路径(一个用于“正常”读取,一个用于对于最后一次阅读),您可以编写一段代码,它可以处理r < n案例,并让它一直运行。

(另外,正如Zan Lynx在评论中提醒的那样,没有r < n的代码通知,并从中推断出文件结束即将到来。等待r == 0在决定你在档案结束之前。)

答案 1 :(得分:2)

您可以自己从man page阅读:

  

在Linux上,read()(和类似的系统调用)最多会传输          0x7ffff000(2,147,479,552)个字节,返回字节数          实际转移。 (32位和64位都是如此          系统。)

所以即使你有足够的RAM等等,你也无法一次性读取全尺寸的DVD图像 - 但是,这也不是理智的事情。要访问这些大文件,mmap会更好。

除此之外,可能会传递信号,这可能导致退出EINTR并且缓冲区内容不确定。

  

<强>错误

     

[...]

     
      
  • EINTR在读取任何数据之前,呼叫被信号中断;见信号(7)。
  •   

答案 2 :(得分:1)

<块引用>

该函数是否保证将 n 个字节读入缓冲区?或者可以吗 少读书?

不,即使您的文件在结束前有超过 n 个字节,read(fd, buf, n) 函数也不能保证将 n 个字节读入缓冲区然后返回 n .它可以读取更少并返回小于 n 的正值。

请参阅位于 https://man7.org/linux/man-pages/man2/read.2.html

的 Linux 手册页 <块引用>

返回值

如果这个数字小于 请求的字节数;这可能会发生,例如因为较少的字节 现在实际上可用(也许是因为我们接近 文件结尾,或者因为我们正在从管道中读取,或者从 终端),或者因为 read() 被信号中断了。