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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值