为什么我程序中的 read() 系统调用会导致几种不同的可能结果?
Why does the read() system call in my program result in several different possible outcomes?
我无法准确理解 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;
}
查看read系统调用函数:
ssize_t read(int fildes, void *buf, size_t nbyte);
我知道 *buf 是保存读取字节的缓冲区,nbyte 是正在读取的字节数。所以在第一次 read() 之后,只有 infile 的前 2 个字符被读取(“a”和“b”)。为什么输出不只是“abcd”?为什么还有其他可能性,例如“aXbZ”或“abcZ”?
read
版本的手册页说:
read()
attempts to read <i>nbyte</i>
bytes of data from the object referenced by the descriptor <i>fildes
into the buffer pointed to by <i>buf
.
和:
Upon successful completion, read()
, readv()
, and pread()
return the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the end-of-file, but in no other case.
因此,在您描述的情况下,“文件 infile 包含字符串“abcdefghijklmnop””,这两个 read
调用保证将“ab”和“cd”放入 buf
,所以程序将打印“abcd”和一个换行符。 (我不会从字面上理解这个保证。当然系统可以保证它不会允许不相关的中断来阻止 read
完全读取请求的数据,但它不能保证没有硬件故障,例如磁盘驱动器在读取完成前发生故障。)
在其他情况下,当 read
从普通文件以外的源读取时,两个 read
调用中的每一个都可能读取 0、1 或 2 个字节。因此,可能的缓冲区内容是:
Bytes read in first read
Bytes read in second read
Buffer contents
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
我无法准确理解 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;
}
查看read系统调用函数:
ssize_t read(int fildes, void *buf, size_t nbyte);
我知道 *buf 是保存读取字节的缓冲区,nbyte 是正在读取的字节数。所以在第一次 read() 之后,只有 infile 的前 2 个字符被读取(“a”和“b”)。为什么输出不只是“abcd”?为什么还有其他可能性,例如“aXbZ”或“abcZ”?
read
版本的手册页说:
read()
attempts to read<i>nbyte</i>
bytes of data from the object referenced by the descriptor<i>fildes
into the buffer pointed to by<i>buf
.
和:
Upon successful completion,
read()
,readv()
, andpread()
return the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the end-of-file, but in no other case.
因此,在您描述的情况下,“文件 infile 包含字符串“abcdefghijklmnop””,这两个 read
调用保证将“ab”和“cd”放入 buf
,所以程序将打印“abcd”和一个换行符。 (我不会从字面上理解这个保证。当然系统可以保证它不会允许不相关的中断来阻止 read
完全读取请求的数据,但它不能保证没有硬件故障,例如磁盘驱动器在读取完成前发生故障。)
在其他情况下,当 read
从普通文件以外的源读取时,两个 read
调用中的每一个都可能读取 0、1 或 2 个字节。因此,可能的缓冲区内容是:
Bytes read in first read | Bytes read in second read | Buffer contents |
---|---|---|
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 |