read()函数的运行逻辑
函数原型
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
fd:
文件描述符buf:
缓冲区count:
缓冲区的数据长度
运行逻辑
read()
函数每次读取内容大小其实由缓冲区大小决定,每次调用read()
时,都会尽可能多地从文件中读取数据,存放到缓冲区内(读取数据的长度一般为缓冲区的长度),只有在读到文件末尾的
E
O
F
EOF
EOF时才会返回0,代表读完整个文件。
是的,你的理解是正确的。read()
函数每次读取的内容是由你指定的缓冲区大小决定的,它会尝试尽可能多地读取数据。每次调用 read()
时,它会返回实际读取到的字节数,而不是总是返回 0
。只有当文件已经被完全读取到末尾,且没有更多数据可供读取时,read()
才会返回 0
,表示到达文件末尾。
示例流程
假设你有一个 10,000 字节的文件,缓冲区大小为 4096 字节。
-
第一次调用
read()
:read()
从文件开始处读取 4096 字节,并将其存入缓冲区buf
中。read()
返回4096
,表示读取了 4096 字节。
-
第二次调用
read()
:read()
继续读取文件的下一个 4096 字节,依然将其存入buf
中。read()
返回4096
,表示又读取了 4096 字节。
-
第三次调用
read()
:- 文件还剩 1408 字节(10,000 - 2 * 4096),
read()
读取剩下的 1408 字节,填充缓冲区的前部分。 read()
返回1408
,表示读取了文件的最后一部分数据。
- 文件还剩 1408 字节(10,000 - 2 * 4096),
-
第四次调用
read()
:- 这时,文件已经被完全读取,
read()
没有更多数据可读取。 read()
返回0
,表示文件已到达末尾(EOF)。
- 这时,文件已经被完全读取,
总结
read()
每次调用会读取指定缓冲区大小的数据,直到到达文件末尾。- 在文件没有读完之前,
read()
返回读取的字节数(非零)。 - 只有当文件被完全读取时,
read()
才会返回0
,表示没有更多的数据可读了。
拷贝操作
基于read()
的特性,可以如此进行文件拷贝工作:
// 3. 循环读文件, 循环写文件
char buf[4096];
int len = -1;
while( (len = read(fd1, buf, sizeof(buf))) > 0 )
{
// 将读到的数据写入到另一个文件中
write(fd2, buf, len);
}
作者: 苏丙榅
链接: https://subingwen.cn/linux/file-io/#2-3-%E6%96%87%E4%BB%B6%E6%8B%B7%E8%B4%9D
来源: 爱编程的大丙
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。