C语言中fstat、stat和lstat 区别

简介:

在写应用程序的时候发现我们经常回去检测一个文件的大小,有了大小才能映射这个文件到内存上,方便我们直接操作。

在介绍三者的区别之前,首先介绍的是一个非常重要的结构体类型,名字叫做struct stat,这是一个保存文件状态信息的结构体,其类型如下:


struct stat 

    dev_t     st_dev;     /* 文件所在设备的标识  */ 
     ino_t     st_ino;     /* 文件结点号  */ 
   mode_t    st_mode;    /* 文件保护模式  */ 
   nlink_t   st_nlink;   /* 硬连接数  */ 
   uid_t     st_uid;     /* 文件用户标识  */ 
   gid_t     st_gid;     /* 文件用户组标识  */ 
   dev_t     st_rdev;    /* 文件所表示的特殊设备文件的设备标识  */ 
   off_t     st_size;    /* 总大小,字节为单位  */ 
   blksize_t st_blksize; /* 文件系统的块大小  */ 
   blkcnt_t  st_blocks;  /* 分配给文件的块的数量,512字节为单元  */ 
   time_t    st_atime;   /* 最后访问时间  */ 
   time_t    st_mtime;   /* 最后修改时间  */ 
   time_t    st_ctime;   /* 最后状态改变时间  */ 
}; 

tips:这里需要注意的是st_mode这个域不像其他域那么容易使用,需要一些宏予以配合。实际上这些宏就是一些特定位置为1的二进制数的绰号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。 

文件类型标志包括:
S_IFBLK:文件是一个特殊的块设备
S_IFDIR:文件是一个目录
S_IFCHR:文件是一个特殊的字符设备
S_IFIFO:文件是一个FIFO设备
S_IFREG:文件是一个普通文件
S_IFLNK:文件是一个符号链接

其他模式标志包括:
S_ISUID:文件设置了SUID位
S_ISGID:文件设置了SGID位
S_ISVTX:文件设置了sticky位

用于解释st_mode标志的掩码包括:
S_IFMT:文件类型
S_IRWXU:属主的读/写/执行权限,可以分成S_IXUSR, S_IRUSR, S_IWUSR
S_IRWXG:属组的读/写/执行权限,可以分成S_IXGRP, S_IRGRP, S_IWGRP
S_IRWXO:其他用户的读/写/执行权限,可以分为S_IXOTH, S_IROTH, S_IWOTH

还有一些用于帮助确定文件类型的宏定义,这些和上面的宏不一样,这些是带有参数的宏,类似与函数的使用方法:

S_ISBLK:测试是否是特殊的块设备文件
S_ISCHR:测试是否是特殊的字符设备文件
S_ISDIR:测试是否是目录
S_ISFIFO:测试是否是FIFO设备
S_ISREG:测试是否是普通文件
S_ISLNK:测试是否是符号链接
S_ISSOCK:测试是否是socket

fstat/stat/lstat系统调用
    
功能描述:   
获取一些文件相关的信息。 
  
用法:   
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 


int stat(const char *path, struct stat *buf); 

int fstat(int filedes, struct stat *buf); 
int lstat(const char *path, struct stat *buf); 
参数:   
path:文件路径名。 
filedes:文件描述词。 
buf:保存文件信息的结构体 
返回说明:   
成功执行时,返回0。失败返回-1,errno被设为以下的某个值   
EBADF:  文件描述词无效 
EFAULT: 地址空间不可访问 
ELOOP:  遍历路径时遇到太多的符号连接 
ENAMETOOLONG:文件路径名太长 
ENOENT:路径名的部分组件不存在,或路径名是空字串 
ENOMEM:内存不足 
ENOTDIR:路径名的部分组件不是目录  
下面放大的部分是他们的区别:
 fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路经直接写就可以了。

stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的


下面用一个例子还说明:



这个file文件是我自己随便写的一个文件,可以是任何文件,但是要有可读权限。

目录
相关文章
|
4月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
4月前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
5月前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
5月前
|
存储 C语言
C语言:普通局部变量、普通全局变量、静态局部变量、静态全局变量的区别
C语言中,普通局部变量在函数内部定义,作用域仅限于该函数;普通全局变量在所有函数外部定义,作用域为整个文件;静态局部变量在函数内部定义但生命周期为整个程序运行期;静态全局变量在所有函数外部定义,但仅在定义它的文件内可见。
341 10
|
5月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
5月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
5月前
|
存储 编译器 C语言
C语言:数组名作为类型、作为地址、对数组名取地址的区别
在C语言中,数组名可以作为类型、地址和取地址使用。数组名本身代表数组的首地址,作为地址时可以直接使用;作为类型时,用于声明指针或函数参数;取地址时,使用取地址符 (&),得到的是整个数组的地址,类型为指向该类型的指针。
|
5月前
|
存储 缓存 C语言
C语言:链表和数组有什么区别
C语言中,链表和数组是两种常用的数据结构。数组是一种线性结构,元素在内存中连续存储,通过下标访问,适合随机访问且大小固定的情况。链表由一系列不连续的节点组成,每个节点存储数据和指向下一个节点的指针,适用于频繁插入和删除操作的场景,链表的大小可以动态变化。
|
5月前
|
编译器 C语言
C语言:typedef 和 define 有什么区别
在C语言中,`typedef`和`#define`都是用来创建标识符以简化复杂数据类型或常量的使用,但它们之间存在本质的区别。`typedef`用于定义新的数据类型别名,它保留了数据类型的特性但不分配内存。而`#define`是预处理器指令,用于定义宏替换,既可用于定义常量,也可用于简单的文本替换,但在编译前进行,过度使用可能导致代码可读性下降。正确选择使用`typedef`或`#define`可以提高代码质量和可维护性。
|
5月前
|
移动开发 C语言
C语言:&&和&、||和|有什么区别
在C语言中,&&和||是逻辑运算符,分别表示逻辑与(AND)和逻辑或(OR),它们用于连接两个布尔表达式,只有当两边都为真时&&返回真,||在至少一边为真时返回真;&和|是位运算符,对应地进行位级的与、或操作,它们对操作数的二进制位进行逐位处理。&&和||具有短路特性,而&和|没有。
3635 1