您的位置:首页 > 运维架构 > Linux

Linux中fstat、stat和lstat的用法与区别

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

struct stat结构体

首先隆重介绍的是一个非常重要的”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  该文件上硬连接的个数

在Linux中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;     //最后一次改变时间(指属性)
};
大家一定注意到了,在上面列举域的时候,我在st_mode处使用了黑体加粗标识,原因在于这个域不像其他域那么容易使用,其他的域的值显而易见,而st_mode域是需要一些宏予以配合才能使用的。其实,通俗说,这些宏就是一些特定位置为1的二进制数的外号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。

st_mode 定义了下列数种情况: 

    S_IFMT   0170000                  文件类型的位遮罩 

    S_IFSOCK 0140000              scoket 

    S_IFLNK 0120000                 符号连接 

    S_IFREG 0100000                一般文件 

    S_IFBLK 0060000                 区块装置 

    S_IFDIR 0040000                 目录 

    S_IFCHR 0020000               字符装置 

    S_IFIFO 0010000                  先进先出 

    S_ISUID 04000                              文件的(set user-id on execution)位 

    S_ISGID 02000                              文件的(set group-id on execution)位 

   S_ISVTX 01000                               文件的sticky位 

    S_IRUSR(S_IREAD) 00400        文件所有者具可读取权限 

    S_IWUSR(S_IWRITE)00200      文件所有者具可写入权限 

    S_IXUSR(S_IEXEC) 00100         文件所有者具可执行权限 

    S_IRGRP 00040             用户组具可读取权限 

    S_IWGRP 00020             用户组具可写入权限 

    S_IXGRP 00010             用户组具可执行权限 

    S_IROTH 00004             其他用户具可读取权限 

    S_IWOTH 00002             其他用户具可写入权限 

    S_IXOTH 00001             其他用户具可执行权限 


stat函数:

表头文件:    

#include <sys/stat.h>
#include <unistd.h>
定义函数:   
int stat(const char *file_name, struct stat *buf);
函数说明:    通过文件名filename获取文件信息,并保存在buf所指的结构体stat中 

返回值:     执行成功则返回0,失败返回-1,错误代码存于errno 

错误代码: 

    ENOENT         参数file_name指定的文件不存在 

    ENOTDIR        路径中的目录存在但却非真正的目录 

    ELOOP          欲打开的文件有过多符号连接问题,上限为16符号连接 

    EFAULT         参数buf为无效指针,指向无法存在的内存空间 

    EACCESS        存取文件时被拒绝 

    ENOMEM         核心内存不足 

    ENAMETOOLONG   参数file_name的路径名称太长 

例子:

#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
}


fstat、stat和lstat的区别:

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系统调用没有这个本事,它只能对符号链接文件睁一只眼闭一只眼,直接去处理链接所指文件喽)

转载自:

http://www.cnitblog.com/guopingleee/archive/2008/11/13/51411.aspx

http://xinzhiwen198941-163-com.iteye.com/blog/993213
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: