c - 为什么我的程序中的 read() 系统调用会导致几种不同的可能结果?
问题描述
我在理解 read() 的工作原理时遇到了一些麻烦。例如,给定以下程序,文件 infile 包含字符串“abcdefghijklmnop”:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd;
char buf[5] = "WXYZ";
fd = open("infile", O_RDONLY);
read(fd, buf, 2);
read(fd, buf+2, 2);
close(fd);
printf("%c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]);
return 0;
}
查看读取系统调用函数:
ssize_t read(int fildes, void *buf, size_t nbyte);
我知道 *buf 是保存读取字节的缓冲区,而 nbyte 是正在读取的字节数。所以在第一次 read() 之后,只读取了 infile 的前 2 个字符(“a”和“b”)。为什么输出不只是“abcd”?为什么还有“aXbZ”或“abcZ”等其他可能性?
解决方案
我的版本的手册页read
说:
read()
尝试nbyte
从描述符引用的对象中读取字节数据到 .fildes
指向的缓冲区中buf
。
和:
成功完成后,返回
read()
实际读取并放入缓冲区的字节数。如果描述符引用了一个在文件结尾之前剩余那么多字节的普通文件,则系统保证读取请求的字节数,但在其他情况下不会。readv()
pread()
因此,在您描述的情况下,使用“包含字符串“abcdefghijklmnop”的文件infile”,这两个read
调用保证将“ab”和“cd”放入buf
,因此程序将打印“abcd”和换行符特点。(我不会从字面上理解这个保证。当然系统可以保证它不会允许无关的中断来阻止read
完全读取请求的数据,但它不能保证没有硬件故障,例如磁盘驱动器在读取完成。)
在其他情况下,当read
从普通文件以外的源读取时,两个read
调用中的每一个都可能读取 0、1 或 2 个字节。因此,可能的缓冲区内容是:
首次读取的字节数 | 第二次读取的字节数 | 缓冲区内容 |
---|---|---|
0 | 0 | WXYZ |
0 | 1 | WXaZ |
0 | 2 | WXab |
1 | 0 | aXYZ |
1 | 1 | aXbZ |
1 | 2 | aXbc |
2 | 0 | abYZ |
2 | 1 | abcZ |
2 | 2 | abcd |
推荐阅读
- karate - 在空手道中使用逻辑 AND/OR 和模糊匹配标记
- matlab - 如何从 ND 矩阵中提取 3D 矩阵?
- ios - 让 UIImageView 通过点击查看它背后
- heading - Apiary.io API 文档编辑器中的“介绍”和“参考”标题可以隐藏或修改吗?
- chisel - 为什么 DspContext 不能像 withNumAddPipes 这样工作?
- mysql - 使用 where in 子句 mysql 查询选择五个特定行和另一个随机行获取限制 10
- python - 返回所有任务不返回已完成的任务
- java - 如何将项目添加到选择后刷新的组合框?
- angular - 视图初始化后更改 ng bootstrap 活动选项卡
- kotlin - Kotlin继承:在序列化和反序列化到/从json之后对象不相等