直接上代码:
#include <stdio.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <unistd.h> int main() { FILE *f1 = fopen("./sysv_msgque.cpp", "r"); printf("lseek():%d ", ftell(f1)); FILE *f2 = fopen("./sysv_msgque.cpp", "r"); // f1、f2相互独立 printf("lseek():%d ", ftell(f2)); char buffer[256]; int r_size; r_size = fread(buffer, 1, 10, f1); printf("%s ", buffer); r_size = fread(buffer, 1, 5, f2); printf("%s ", buffer); printf("lseek():%d ", ftell(f1)); printf("lseek():%d ", ftell(f2)); int o1 = open("./sysv_msgque.cpp", O_RDONLY); int o2 = open("./sysv_msgque.cpp", O_RDONLY); int o3 = dup(o2); // o1、o2之间互相不影响,o3、o2之间共用一个文件表项,共享文件位移量 memset(buffer, 0, 256); lseek(o1 , 5 , SEEK_SET); read(o1, buffer, 1); printf("%s ", buffer); memset(buffer, 0, 256); read(o2, buffer, 1); printf("%s ", buffer); memset(buffer, 0, 256); read(o3, buffer, 1); printf("%s ", buffer); }
测试结果是:每一次打开的文件描述符(即使打开相同文件)之间使用的是不同的文件表项,由dup函数复制返回的两个文件描述符才会使用相同的文件表项,共享各类值。
引用自 https://blog.csdn.net/qq_28114615/article/details/94590598 :
1. 每次调用open或者create(内部实际上还是调用的open),都会对新打开的文件分配一个file结构体,并且将打开文件的标志、状态、权限等信息填入这个file结构体中。这个file结构体也叫文件表项;
2. 磁盘中的每个文件都对应一个i-node,每一个文件表项都会指向一个文件的i-node,但是同一文件的i-node可以对应多个文件表项(当多次调用open打开同一个文件时就会出现这种情况,不管是同一进程多次打开同一文件(如图中A进程的0号和2号文件描述符对应两个文件表项,但是最终指向同一i-node即同一文件),还是不同进程多次打开同一文件(如图中A进程3号文件描述符和B进程的3号文件描述符));
3. 同一进程下的不同文件描述符是可以指向同一文件表项,即最终指向同一文件;
4. 子进程在创建时会拷贝父进程的打开文件描述符表,因此父子进程是共享文件表项的;
5. 指向同一文件表项的不同文件描述符共享文件标志、文件偏移等信息;
6. 对于指向同一文件表项的两个不同文件描述符,即使其中一个文件描述符关闭了,只要仍然有文件描述符指向这个文件表项,那么就依然能通过这个文件表项访问文件,直到所有指向该文件表项的文件描述符都关闭了才不能再进行访问;