fd与FILE的比较

在Linux操作系统中,文件管理通过file结构体和fd进行。file结构体描述单个文件,而fd是文件描述符,用于进程访问文件。当open函数打开文件时,会创建file结构体并在进程的files_struct中保存fd,使得进程通过fd访问文件。FILE是C库中的文件描述结构,封装了fd,C库的f开头IO函数是对系统调用的封装。

Linux中一切皆文件,这句话我们都知道,可见文件的重要性,因此文件的管理在Linux中占据了很大比重,那么操作系统怎么管理文件的呢?
要管理一个东西,那么必须经历两个步骤——描述和组织。当我们打开一个文件时,系统就会生成一个叫做file的结构体,系统正是用这个file结构体来描述单个文件的;既然已经描述了那么就要组织起来了,系统就会用一个数据结构把所有的文件都组织在一起以方便管理,而我们的进程要能访问这些文件,那么这个数据结构也要与进程关联起来。在Linux中,进程与文件的模型是这样的:
这里写图片描述
进程的PCB中保存着一个指向文件组织结构的一个指针,而对于每个打开的文件,在文件组织结构的文件指针数组中都会有一个指针指向它,因此进程只要通过files指针访问到fd_array就可以进入打开的文件了。
所以,当我们用open函数打开一个文件时,其过程为:操作系统生成一个新的file结构体来保存这个文件的信息,并在files_struct的文件数组fd_array中生成一个指向这个file结构体的指针,然后向进程返回这个指针的下标值。而这个下标值正是文件描述符fd,在进程中也正是通过这个fd来访问目的文件。所以,fd就是指向所打开文件的指针在files_struct中的数组 fd_array里面的下标值。
必须注意的是files_struct与file都是在内核中存在的。FILE是C库中的文件描述结构体,这是一个用户层次的结构,里面封装了fd,其结构体定义为:
这里写图片描述
看到这里,我们能知道,C库中的FILE结构体也是通过fd来管理文件的,当C程序用fiopen打开一个文件时,其实质是通过调用open函数来进行操作的。也就是说FILE结构是对fd的封装,而C库中带f的一系列IO函

在C语言中,当有一个`FILE *fd`指针时,可以通过以下步骤实现同步操作,确保文件缓冲区中的数据被写入磁盘。 首先,使用`fflush`函数将`FILE`对象的用户空间缓冲区中的数据刷新到内核缓冲区。`fflush`函数的原型如下: ```c #include <stdio.h> int fflush(FILE *stream); ``` 这里的`stream`就是`FILE *`类型的文件指针。 然后,使用`fsync`或`fdatasync`函数将内核缓冲区的数据刷新到磁盘。要使用这两个函数,需要先通过`fileno`函数获取文件描述符,因为`fsync`和`fdatasync`函数操作的是文件描述符而非`FILE *`指针。`fileno`函数的原型如下: ```c #include <stdio.h> int fileno(FILE *stream); ``` `fsync`和`fdatasync`函数的原型如下: ```c #include <unistd.h> int fsync(int fd); int fdatasync(int fd); ``` `fsync`会同步文件的所有元数据和数据到磁盘,而`fdatasync`只同步文件的数据部分,不同步元数据(如文件的访问时间等)。 以下是一个示例代码: ```c #include <stdio.h> #include <unistd.h> int main() { FILE *fd = fopen("test.txt", "w"); if (fd == NULL) { perror("fopen"); return 1; } // 写入一些数据 fputs("Hello, World!\n", fd); // 刷新用户空间缓冲区到内核缓冲区 if (fflush(fd) != 0) { perror("fflush"); fclose(fd); return 1; } // 获取文件描述符 int file_descriptor = fileno(fd); if (file_descriptor == -1) { perror("fileno"); fclose(fd); return 1; } // 同步内核缓冲区到磁盘 if (fsync(file_descriptor) != 0) { perror("fsync"); fclose(fd); return 1; } // 关闭文件 fclose(fd); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值