文件描述符指向文件表,一个进程默认打开1024个文件描述符。
文件表中保存了:文件状态标志(可读、可写、追加、同步、非阻塞等)、文件偏移量、refcnt(引用计数)、v结点指针(指向v结点表--v结点信息stat函数可以查看、i结点信息)
文件在磁盘块的位置: i结点信息.
若一个进程两次打开同一个文件,共享V节点表。
1 #include<unistd.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<fcntl.h> 5 #include<stdlib.h> 6 #include<stdio.h> 7 #include<errno.h> 8 #include<string.h> 9 #define ERR_EXIT(m) 10 do 11 { 12 perror(m); 13 exit(EXIT_FAILURE); 14 }while(0) //宏要求一条语句 15 int main(int argc,char*argv[]) 16 { 17 int fd1; 18 int fd2; 19 //同一个进程打开两次。test.txt中为hello 20 fd1=open("test.txt",O_RDONLY); 21 if(fd1==-1) 22 ERR_EXIT("open error"); 23 fd2=open("test.txt",O_RDWR); 24 if(fd2==-1) 25 ERR_EXIT("open error"); 26 char buf1[1024]={0}; 27 char buf2[1024]={0}; 28 //文件表项不共享,状态标识可以不同,偏移量也独立,所以读取内容相同.但v节点表共享 29 read(fd1,buf1,5); 30 printf("buf1=%s ",buf1); 31 read(fd2,buf2,5); 32 printf("buf2=%s ",buf2); 33 34 write(fd2,"AAAAA",5);//偏移5个位置开始写入 35 memset(buf1,0,sizeof(buf1));//在内存中填充 36 read(fd1,buf1,5);//共享v节点信息,i节点信息,所指向磁盘数据改变。还是从偏移5位置开始 37 printf("buf1=%s ",buf1); 38 /* 39 buf1=hello 40 buf2=hello 41 buf1=AAAAA 42 */ 43 close(fd1); 44 close(fd2); 45 //两个进程打开同一个文件,fd不一定相同,不同进程描述符不一 一对应。
46 //复制文件描述符实现IO重定向。dup(fd),得到新的文件描述符跟前一个fd指向同一个文件,引用计数refcnt变为2。
//如图,若我们把1文件描述符关闭,复制3文件描述符。复制文件描述符时,从0开始搜索空闲描述符,搜索到1,那么1就指向3指向的文件,实现了标准输出的重定向。
47 int fd; 48 fd=open("test2.txt",O_WRONLY); 49 if(fd==-1) 50 ERR_EXIT("open error"); 51 close(1);//关闭标准输出 52 dup(fd);//1被关闭,所以复制后返回的文件描述符为1. 此时1也指向test.txt.新文件描述符一定是当前最小的 53 printf("hi ");//不再输出到屏幕,而是到test2.txt. 输出到1所指向的设备。 54 return 0; 55 }