Linux 编程中的 open() 与 fdopen() 区别与联系
概述
Linux 编程中对打开文件的操作提供了 open、fopen()、fdopen() 几种方法,本文简要地介绍他们的异同。
不同点
头文件与函数原型不同
#include <fcntl.h>
int open(const char *pathname, int flags, ...
/* mode_t mode */ );
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *restrict pathname, const char *restrict mode,
FILE *restrict stream);
用法上的区别
open() 提供了一个较低级别的接口,属于低级磁盘 IO 接口,也称为 Linux 文件IO,可以打开一个外设设备、文件等对象。
fdopen() 提供的是文件对象接口,也称为标准文件 IO。主要操作数据文件。你可以使用 fdopen() 打开由 open 打开的文件句柄:
#include < fcntl.h>
#include < stdio.h>
int main(void)
{
char pathname[] = “/tmp/myfile”;
int fd_int;
FILE *fp;
if ((fd_int = open(pathname, O_RDONLY)) == -1) {
printf(“ open failed\n”,);
return;
}
if ((fp=fdopen(fd_int , “r”)) == NULL) {
printf(“fdopen error for %s\n”, pathname);
} else {
printf(“fdopen seccess for %s\n”, pathname);
fclose(fp);
}
进一步理解 open 与 fdopen 的使用场景
- open 是一个系统调用,具体实现视系统对其支持的情况,多用于 Unix 的系统,并且它直接与内核交互。通常支持 POSIX 标准的系统会支持它。当你需要打开一个低级的 IO 设备,如RS232 的 串口外设、管道设备时,请使用它。
- fdopen 是一个库函数,支持LibC 以及典型 C 语言的系统都支持它,从这点说,它具备更好的可移植特性。往往只是普通的数字、文字文件。
- Linux 中即支持 POSIX 标准也支持 LibC,所以可以同时使用 open、fdopen。
- 系统调用是个复杂的话题,open 的实现可能会直接操作底层设备,导致频繁的系统调用,增加系统开销。而 fdopen() 自带了一些缓存机制,数据会先缓存到缓冲区,必要时触发系统调用,访问到实际的存储区域。
- open 打开的对象称为文件描述符,其直接对应实际的底层对象,而 fdopen 打开的对象称为“流”,即 stream,它与缓冲区进行交互。
总结
- 本文重点介绍了 open()、fdopen() 在用法、标准、开销、上的异同。