最近在看大神W.Richard Stevens
的Advanced Programming in the UNIX® Environment
,简称APUE
。
以下是我写的读书笔记。
- File I/O
UNIX下一切皆文件,内核通过文件描述符来访问文件。
每个进程默认打开3个file descriptor: STDIN_FILENO
, STDOUT_FILENO
, STDERR_DILENO
每个进程都有一个entry in process table entry
,每个entry
可以看作是一个(python中的)字典,字典的key是文件描述符,value是一个Tuple,Tuple中的元素为(file descriptor flags
, A pointer to a file table entry
)
内核为所有打开的文件维护一个file table
, 其中的每个entry包含:
(a) The file status flags for the file, such as read, write, append, sync, and
nonblocking;
(b) The current file offset
(c) A pointer to the v-node table entry for the file
Each open file (or device) has a v-node structure that contains information about the type of file and pointers to functions that operate on the file.
每个打开的文件(或设备)都有一个v-node
的结构,其包含了文件的元信息。(Linux has no v-node.)
用图表示:
- 习题 3.6:
If you open a file for read–write with the append flag, can you still read from anywhere in the file using lseek? Can you use lseek to replace existing data in the file? Write a program to verify this.
答:可以。
举个例子:有如下两个程序。
3.6_1.c, 编译为w
#include
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
int fd, i;
char buf[] = "123456789abcdefghijklmnopqrstuvwxyz";
fd = open("a.txt", O_RDWR| O_CREAT | O_APPEND);
if (fd == -1) {
perror("open");
exit(1);
}
for (i=0; i
3.6_2.c, 编译为r
#include
#include
#include
#include
#include
#include
#define BUFSIZE 32
int main(int argc, char const *argv[])
{
int fd;
fd = open("a.txt", O_WRONLY);
char buf[BUFSIZE] = "0";
if (fd == -1) {
perror("open");
exit(1);
}
lseek(fd, 0, SEEK_SET);
write(fd, buf, 1);
printf("The written char is %c\n", buf[0]);
read(fd, buf, 1);
printf("The read char is %c\n", buf[0]);
return 0;
}
我们先运行w,(等几秒)然后再运行r。这里会生成a.txt
文件,我们可以看看文件的内容:
0234567
程序3.6_2.c
lseek到文件开头处 并且替换了文件开头的1
。
这说明不同进程间是可以共享文件的,如果有多个进程同时操作文件,可能会造成文件内容的损坏。