小田
2023/02/16阅读:19主题:草原绿
fopen/fdopen/lstat/fstat
fopen与fdopen,lstat与fstat的区别
「fopen」,「lstat」是我们经常使用的API,通过「fopen」我们可以打开一个文件流,通过「lstat」我们可以拿到一个文件的基本信息,但是今天工作时用「fopen/lstat」写的代码,被同事建议用「fdopen/lstat」代替,就想研究下这俩函数分别有啥区别。
1.fopen
#include <stdio.h>
FILE *fopen(const char *restrict` *filename*`, const char *restrict` *mode*`);
fopen () 函数将打开路径名为「filename」指向的字符串的文件,并关联一个流。
「mode」参数指向一个字符串。如果字符串是以下之一,文件将以指定的模式打开。否则,行为未定义。
-
r 或 rb
打开文件进行阅读。
-
w 或 wb
截断为零长度或创建用于写入的文件。一个 或 一个附加; 打开或创建文件以在文件末尾写入。
-
r+ 或 rb+ 或 r+b
打开文件进行更新(读取和写入)。
-
w+ 或 wb+ 或 w+b
截断为零长度或创建文件以进行更新。
-
a+ 或 ab+ 或 a+b
附加; 打开或创建文件以进行更新,在文件末尾写入。
字符b
无效,但允许符合 「ISO C」 标准。如果文件不存在或无法读取,则以读取模式打开文件(r作为模式参数中的第一个字符)将失败。
成功完成后,fopen () 将返回一个指向控制流的对象的指针。否则,应返回空指针, 「errno」应设置为指示错误。
2.fdopen
#include <stdio.h>
FILE *fdopen(int fildes, const char *mode);
打开已存在的文件描述符,使标准I/O流与该文件相结合。主要用于fopen不能打开的「特殊文件」(如管道和网路通信等),这时必须先调用设备专用函数以获得一个文件描述符,然后再用fdopen使一个标准I/O与该文件描述符相结合。
fdopen的第一个参数使用的是open()返回的「文件描述符」fd,文件描述符是从open ()、dup ()、creat ()或pipe ()等调用获得的,这些调用打开文件但不返回「流」。也就是说调用fdopen时,文件已经存在了(即使不存在时,在open()这一步已经创建完了)。
mode参数也有所不同。fopen中当mode中含有“w”时,会把当前文件截断为0。而在fdopen()的mode参数”w“没有这样的作用,open()中是否用了「O_TRUNC」才能决定fdopen打开的文件是否会被截断为0。其他参数与fopen保持一致.
成功完成后,fdopen () 应返回一个指向流的「指针」;否则,应返回空指针并设置「errno」以指示错误。
3.stat/lstat/fstat
「stat」系统调用系列包括了「fstat」、「stat」和「lstat」,它们都是用来返回“相关文件状态信息”的,三者的不同之处在于设定源文件的方式不同。
首先看一下结构体「struct stat」
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
}
通常 struct stat是个传入参数, 一般可以借助stat lstat和fstat三种方式来填充struct stat的信息
#include <sys/stat.h>
#include <unistd.h>
int fstat(int filedes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
stat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open ()、dup ()、creat ()或pipe ()等系统调用后才能得到的,而文件全路经直接写就可以了。这也就意味着fstat可以打开一些stat和lstat无法打开的「特殊文件」,像fdopen似的.
stat和lstat的区别:当文件是一个「符号链接」时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接「指向」的文件的信息。
关注公众号 【程序员DeRozan】,免费领取海量资料及3yuan xianjin红包。
作者介绍