假设我有一个文件,其文件描述符在EOF之前有超过n个字节,并且我为n个字节调用read()系统调用。该函数是否保证将n个字节读入缓冲区?或者它可以少读?
答案 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() 被信号中断了。