“unistd.h”中的函数“read”的读取限制是什么?

7
标准的unix C语言有这个函数:
ssize_t read(int fd, void *buf, size_t count);

但是,这个“read”函数一次可以读取的最大字节数是多少?

2
@Tomalak:这个问题与语言无关。 - Puppy
4个回答

12

来自man read(2):

read()试图从文件描述符fd中读取最多count个字节,并将其存储到buf指向的缓冲区中。

如果count为零,read()返回零并且没有其他结果。如果count大于SSIZE_MAX,则结果未指定。

SSIZE_MAX的值取决于您的系统,但通常类似于signed long的最大值,这通常是231(32位系统)或263(64位系统)。

231个字节是2 GB,因此您可能是安全的。实际上,设备驱动程序/缓冲区/网络I/O永远不会一次性给您提供一个2 GB的数据块。


3

引用自IEEE标准1003.1(也称为POSIX.1)

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

因此,您需要在目标平台上检查man 2 read。例如,FreeBSD手册在错误部分中说:

[EINVAL] nbytes的值大于INT_MAX。


2
通常情况下,可以读取与buf中可用的字节数相同的字节。实际上,底层设备驱动程序(无论是文件系统、网络还是管道)如果没有更多可用的内容,则会返回少于您所需的内容。
因此,read的特定行为取决于内核中底层驱动程序的实现。
这就是为什么始终检查read的返回值并检查实际读取的字节数非常重要。

1
read()函数需要传入一个打开的文件描述符、缓冲区地址和字节数count。它试图从描述符所描述的文件中读取count个字节到缓冲区中。重要的是要确保buf指向至少count个字节的存储空间!

它可以读取缓冲区所能容纳的最大值,限制为SSIZE_MAX以及硬件的限制。


2
你不能请求超过SIZE_MAX字节的数据,而且由于你可能想知道实际读取了多少(并遵循规范),所以你被限制在SSIZE_MAX字节内。 - janneb
@janne:但是SIZE_MAX是0xFFFF'FFFF(VC++)!你真的指的是那个数字吗? - jondinham
2
@Paul:SIZE_MAX不等于SSIZE_MAX - Lightness Races in Orbit
无论是“signed”还是“unsigned”,这个*_MAX仍然是一个32位的数字,对于常规文件来说非常大。如果可能的话,能够读取*_MAX字节真的很好! - jondinham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接