fstat、stat和lstat 区别(转)

stat系统调用系列包括了fstat、stat和lstat,它们都是用来返回“相关文件状态信息”的,三者的不同之处在于设定源文件的方式不同。

1

首先隆重介绍的是一个非常重要的”VIP”人物,他是fstat, stat和lstat三者都要用到的一个结构体类型,名字叫做struct stat。可以说,没有这个struct stat的支持,上述三个系统调用将寸步难行。

这个struct stat结构体在不同的UNIX/Linux系统中的定义是有小的区别的,但你完全不用担心,这并不会影响我们的使用。

在struct stat结构体中我们常用的且各个平台都一定有的域是:

st_mode 文件权限和文件类型信息 (记住这个黑体橘红色)

st_ino   与该文件关联的inode

st_dev   保存文件的设备

st_uid   文件属主的UID号

st_gid   文件属主的GID号

st_atime 文件上一次被访问的时间

st_ctime 文件的权限、属主、组或内容上一次被修改的时间

st_mtime 文件的内容上一次被修改的时间。(和st_ctime的不同之处显而易见)

st_nlink  该文件上硬连接的个数

我分别提取了solaris(UNIX)和fedora(Linux)的struct stat结构体的原始定义:大家可以自己比对一下便可以发现两者确实有所不同,但主要的域是完全相同的。

solaris的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;
timestruc_t     st_atim;
timestruc_t     st_mtim;
timestruc_t     st_ctim;
blksize_t       st_blksize;
blkcnt_t        st_blocks;
char            st_fstype[_ST_FSTYPSZ];
};

fedora的struct stat定义:

struct stat
{
__dev_t st_dev;                     /* Device.  */
unsigned short int __pad1;
__ino_t st_ino;                     /* File serial number.  */
__mode_t st_mode;                   /* File mode.  */
__nlink_t st_nlink;                 /* Link count.  */
__uid_t st_uid;                     /* User ID of the file’s owner. */
__gid_t st_gid;                     /* Group ID of the file’s group.*/
__dev_t st_rdev;                    /* Device number, if device.  */
unsigned short int __pad2;
__off_t st_size;                    /* Size of file, in bytes.  */
__blksize_t st_blksize;             /* Optimal block size for I/O.  */
__blkcnt_t st_blocks;               /* Number 512-byte blocks allocated. */
struct timespec st_atim;            /* Time of last access.  */
struct timespec st_mtim;            /* Time of last modification.  */
struct timespec st_ctim;            /* Time of last status change.  */
unsigned long int __unused4;
unsigned long int __unused5;
};

2

大家一定注意到了,在上面列举域的时候,我在st_mode处使用了黑体橘红色标识,原因在于这个域不像其他域那么容易使用,其他的域的值显而易见,而st_mode域是需要一些宏予以配合才能使用的。其实,通俗说,这些宏就是一些特定位置为1的二进制数的外号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。

文件类型标志包括:

S_IFBLK:文件是一个特殊的块设备

S_IFDIR:文件是一个目录

S_IFCHR:文件是一个特殊的字符设备

S_IFIFO:文件是一个FIFO设备

S_IFREG:文件是一个普通文件(REG即使regular啦)

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:测试是否是目录(我估计find . -type d的源代码实现中就用到了这个宏)

S_ISFIFO:测试是否是FIFO设备

S_ISREG:测试是否是普通文件

S_ISLNK:测试是否是符号链接

S_ISSOCK:测试是否是socket

3

我们已经学习完了struct stat和各种st_mode相关宏,现在就可以拿它们和stat系统调用相互配合工作了!

int fstat(int filedes, struct stat *buf);

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

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

聪明人一眼就能看出来fstat的第一个参数是和另外两个不一样的,对!fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路经直接写就可以了。

stat和lstat的区别:当文件是一个符号链接
时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。(似乎有些晕吧,这样记,lstat比stat多了一个l,因
此它是有本事处理符号链接文件的,因此当遇到符号链接文件时,lstat当然不会放过。而
stat系统调用没有这个本事,它只能对符号链接文件睁一只眼闭一只眼,直接去处理链接所指文件喽)

fstat、stat和lstat 区别(转)的更多相关文章

  1. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  2. 17、文件IO详解及实例

    上篇文章已经讲过了文件系统的一些基本的概念,这里首先对文件IO进行详细的学习,文件IO也称为系统调用IO,是操作系统为"用户态"运行的进程和硬件交互提供的一组接口,即操作系统内核留 ...

  3. Notes for Apue —— chapter 4 Files and Directories(文件和目录)

    4.1 Introduction 4.2 stat, fstat, fstatat, and lstat Functions The lstat function is similar to stat ...

  4. Python os.md

    os 便携式访问操作系统的特定功能.os模块提供了对特定平台模块(如posix, nt, mac)的封装, 函数提供的api在很多平台上都可以相同使用, 所以使用os模块会变得很方便. 但不是所有函数 ...

  5. 【Linux】文件操作系统调用

    一. 文件描述符 在Linux下使用文件描述符来表示设备文件和普通文件.文件描述符是一个整型的数据,所有对文件的操作都通过文件描述符实现.文件描述符的范围是0~OPEN_MAX,系统中有3个已经分配的 ...

  6. Unix基本系统数据类型和stat结构体

    Unix基本系统数据类型 历史上,某些UNIX变量已与某些C数据类型联系在一起,例如,历史上主.次设备号存放在一个1 6位的短整型中, 8位表示主设备号,另外8位表示次设备号.但是,很多较大的系统需要 ...

  7. 【APUE】Chapter4 File and Directories

    4.1 Introduction unix的文件.目录都被当成文件来看待(vi也可以编辑目录):我猜这样把一起内容都当成文件的原因是便于统一管理权限这类的内容 4.2 stat, fstat, fst ...

  8. UNIX环境高级编程--4

    函数stat fstat fstatat 和 lstat stat函数使用最多的地方可能就是ls -l 命令,用其可以获得有关一个文件的所有信息. 文件类型: (1)普通文件 (2)目录文件 (3)块 ...

  9. nodejs中的文件系统

    . 目录 简介 nodejs中的文件系统模块 Promise版本的fs 文件描述符 fs.stat文件状态信息 fs的文件读写 fs的文件夹操作 path操作 简介 nodejs使用了异步IO来提升服 ...

随机推荐

  1. vue点击tab跳转页面,给点击的tab添加样式,且解决刷新以后点击的tab样式消失问题

    <ul class="nij"> <li v-for="item in nav" @click="selectNav(item.ti ...

  2. hdu1837 看病要排队(优先队列)

    看病要排队 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  3. CentOS-pam认证机制简介

    前言 linux下PAM模块全称是Pluggable Authentication Module for linux(可插入式授权管理模块),该由Sun公司提供,在Linux中,PAM是可动态配置的, ...

  4. quartz使用(整合spring)

    quartz与spring整合后,还是需要Scheduler实例.JobDetail实例.Trigger实例,只不过是用FactoryBean的方式创建了. 在spring-context-suppo ...

  5. opengl键盘回调函数不能获取Ctrl+c的问题

    我要令窗口在按下 Ctrl+c 之后关闭. 关键代码如下: /* 这段代码位于键盘回调函数中 */ if ((glutGetModifiers() == GLUT_ACTIVE_CTRL) & ...

  6. spark运行时出现Neither spark.yarn.jars nor spark.yarn.archive is set错误的解决办法(图文详解)

    不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑          ...

  7. 移动开发:Android官方提供的支持不同屏幕大小的全部方法

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/8830286 原文地址为:http://developer.android.com/ ...

  8. 【计算机网络】HTTP请求和响应格式

    HTTP请求格式:<request-line><headers><blank line>[<request-body>]说明:第一行必须是一个请求行(r ...

  9. 【linux相识相知】VIM编辑器

    Vim是一个类似Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了许多的功能,VIM是自由软件,今天我们就来讲讲VIM的使用方法. 本文是基于centos7上的vim编辑器演示的 ...

  10. vue路由配置

    1.安装 npm install vue-router --save / cnpm install vue-router --save 2.引入并 Vue.use(VueRouter) (main.j ...