函数头文件及原型
查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> struct stat { dev_t st_dev; /* 包含文件的设备的ID */ ino_t st_ino; /* inode值 */ mode_t st_mode; /* 类型及权限 */ nlink_t st_nlink; /* 硬链接数量 */ uid_t st_uid; /* 所有者的用户ID */ gid_t st_gid; /* 所有者的组ID */ dev_t st_rdev; /* 设备ID(如果是特殊文件) */ off_t st_size; /* 总大小,以byte为单位 */ blksize_t st_blksize; /* 文件系统I/O的块大小 */ blkcnt_t st_blocks; /* 分配的512B块数 */ time_t st_atime; /* 最后访问时间 */ time_t st_mtime; /* 最后修改时间 */ time_t st_ctime; /* 上次状态更改的时间 */ }; int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); int lstat(const char *path, struct stat *buf); |
stat与lstat差别就在于l(link),stat会越过链接文件读取原文件,后者则读取链接文件。关于Linux环境的软硬链接可以参考:https://blog.csdn.net/weixin_44498318/article/details/105399439
可以使用以下宏传递结构体成员st_mode查看文件类型:
1 2 3 4 5 6 7 | S_ISREG(m) 常规文件 S_ISDIR(m) 目录 S_ISCHR(m) 字符设备 S_ISBLK(m) 块设备 S_ISFIFO(m) FIFO文件 S_ISLNK(m) 符号链接 S_ISSOCK(m) 套接字文件 |
事实上以下就是st_mode字段定义的标志,也可以相“&”来读取文件的属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | S_IFMT 0170000 文件类型的位遮罩 S_IFSOCK 0140000 套接字 S_IFLNK 0120000 符号连接 S_IFREG 0100000 普通文件 S_IFBLK 0060000 块设备 S_IFDIR 0040000 目录 S_IFCHR 0020000 字符设备 S_IFIFO 0010000 FIFO S_ISUID 0004000 文件的(set user-id on execution)位 S_ISGID 0002000 文件的(set group-id on execution)位 S_ISVTX 0001000 文件的sticky位 S_IRWXU 00700 文件所有者权限的掩码 S_IRUSR 00400 拥有者读权限 S_IWUSR 00200 拥有者写权限 S_IXUSR 00100 拥有者执行权限 S_IRWXG 00070 文件所在组权限的掩码 S_IRGRP 00040 用户组读权限 S_IWGRP 00020 用户组写权限 S_IXGRP 00010 用户组执行权限 S_IRWXO 00007 其他用户权限的掩码 S_IROTH 00004 其他用户读权限 S_IWOTH 00002 其他用户写权限 S_IXOTH 00001 其他用户执行权限 |
返回值
成功返回0,失败返回-1并且设置错误码errno;
示例
先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> int main() { int fd; struct stat buf[3]; // stat函数 if( 0 != stat("./file.txt.soft", &buf[0])) { printf("stat error!\n"); return -1; } printf("stat: The file size is %lu\n", buf[0].st_size); // fstat函数 fd = open("./file.txt.soft", O_RDWR); if(fd < 0) { printf("open file error!\n"); return -1; } if(0 != fstat(fd, &buf[1])) { printf("fstat error!\n"); return -1; } printf("fstat: The file size is %lu\n", buf[1].st_size); close(fd); // lstat函数 if(0 != lstat("./file.txt.soft", &buf[2])) { printf("stat error!\n"); return -1; } printf("lstat: The file size is %lu\n", buf[2].st_size); // 比较stat和lstat if(S_ISLNK(buf[0].st_mode)) printf("stat: It is a link file!\n"); else printf("stat: It is not a link file!\n"); if(buf[2].st_mode & S_IFLNK) printf("lstat: It is a link file!\n"); else printf("lstat: It is not a link file!\n"); return 0; } |
1 2 3 4 5 | stat: The file size is 6 fstat: The file size is 6 lstat: The file size is 8 stat: It is not a link file! lstat: It is a link file! |
可以看到stat和lstat的区别就在于是否会越过链接文件进行读取。