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

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

#include 定义函数:

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

#include

#include

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

相关推荐

Rihanna | 真正的流行之王
365bet娱乐场游戏

Rihanna | 真正的流行之王

07-25 👁️ 9422
做笔录多久会上系统,笔录记录后多久上传系统?
上海方博教育施江浩 老师介绍
365足球比分

上海方博教育施江浩 老师介绍

08-07 👁️ 1602