获取文件的信息 stat()
利用系统调用stat(),lstat(),fstat()可获取与文件有关的信息,其中大部分提取自文件i节点。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
返回所命名文件的相关信息
int fstat(int fd, struct stat *buf);
返回由某个打开文件描述符所指代文件的相关信息
int lstat(const char *path, struct stat *buf);
与stat区别在于,如果文件属于符号链接,那么所返回的信息针对的是符号链接自身而非指向的文件。
系统调用stat()和lstat()无需对所操作的文件本身拥有任何权限,但针对指定的pathname父目录要有
执行(搜索)权限。而只要有有效的文件描述符,fstat()系统调用总是成功。
以上所有系统调用都会在缓冲区中返回一个由startbuf指向的stat结构,其格式如下:
struct stat {
dev_t st_dev; /* ID of device containing file */
//st_dev字段标识文件所驻留的设备
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
//st_mode字段内含有位掩码,起标识文件类型和指定文件权限双重作用
// | | | | U | G | T | R | W | X | R | W | X | R | W | X |
// <-------> <---------------------------------------------->
// 文件类型 权限 (用户、组、其他)
//与常量S_IFMT相与&,可以从该字段中取出文件类型
nlink_t st_nlink; /* number of hard links */
//标识了文件的硬连接数
uid_t st_uid; /* user ID of owner */
//标识文件的属主i
gid_t st_gid; /* group ID of owner */
//表示文件的属组
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
//对于常规文件来说,标识文件的字节数
//对于符号链接来说,则标识链接所指路径名的长度,以字节为单位
//对于共享内存对象来说,则表示对象的大小。
blksize_t st_blksize; /* blocksize for filesystem I/O */
//st_blksize并非底层文件系统的块大小,而是针对文件系统上文件进行io操作时最优块的大小。
blkcnt_t st_blocks; /* number of 512B blocks allocated */
//表示分配给文件的总块数,块大小为512字节,其中包括了为指针块所分配的空间
//实际分配给文件的磁盘块的数量
time_t st_atime; /* time of last access */
//对文件的上次访问时间
time_t st_mtime; /* time of last modification */
//文件的上次修改时间
time_t st_ctime; /* time of last status change */
//文件状态发生变化的时间
};
针对stat结构中的st_mode来检查文件类型的宏:
常量 测试宏 文件类型
S_IFREG S_IFREG() 常规文件
S_IFDIR S_IFDIR() 目录
S_IFCHR S_IFCHR() 字符设备
S_IFBLK S_IFBLK() 块设备
S_IFIFO S_IFIFO() FIFO或管道
S_IFSOCK S_IFSOCK() 套接字
S_IFLNK S_ISLNK() 符号链接
判断文件的类型:
if ((statbuf.st_mode & S_IFMT) == S_IFREG) printf("regular file\n");
等价于:
if (S_ISREG(statbuf.st_mode)) printf("regular file\n");
S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set-user-ID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <time.h>
6 int main(int agrc,char * argv[]){
7 struct stat sb;
8 struct passwd * pwd;
9 if (stat(argv[1],&sb)==-1) {
10 printf("按照以下格式输入:%s filename\n",argv[0]);
11 exit(-1);
12 }
13 printf("文件类型:");
14 switch(sb.st_mode & S_IFMT){
15 case S_IFREG: printf("普通文件"); break;
16 case S_IFDIR: printf("目录"); break;
17 case S_IFCHR: printf("字符设备"); break;
18 case S_IFBLK: printf("块设备"); break;
19 case S_IFIFO: printf("FIFO或管道"); break;
20 case S_IFSOCK: printf("套接字"); break;
21 case S_IFLNK: printf("符号链接");break;
22 default: printf("未知文件类型");break;
23 }
24 printf("\n");
25 printf("%s的硬连接数为:%d\n",argv[1],sb.st_nlink);
26 printf("%s的inode节点为:%d\n",argv[1],sb.st_ino);
27 printf("%s的文件属主为:%d\n",argv[1],sb.st_uid);
28 printf("%s的文件属组为:%d\n",argv[1],sb.st_gid);
29 printf("%s的文件大小为:%d\n",argv[1],sb.st_size);
30 printf("%s的分配文件总块数为:%d\n",argv[1],sb.st_blocks);
31 printf("%s的上次访问时间为:%s",argv[1],ctime(&sb.st_atime));
32 printf("%s的上次修改时间为:%s",argv[1],ctime(&sb.st_mtime));
33 printf("%s的上次文件状态变化时间为:%s",argv[1],ctime(&sb.st_ctime));
34 return 0;
35 }
songxl@ubuntu:~/linuxc/manual$ stat copy
文件:"copy"
大小:7637 块:16 IO 块:4096 普通文件
设备:801h/2049d Inode:280675 硬链接:1
权限:(0775/-rwxrwxr-x) Uid:( 1000/ songxl) Gid:( 1000/ songxl)
最近访问:2015-05-21 19:15:49.094183660 +0800
最近更改:2015-05-21 19:15:33.002184218 +0800
最近改动:2015-05-21 19:15:33.002184218 +0800
创建时间:-
songxl@ubuntu:~/linuxc/manual$ a.out copy
文件类型:普通文件
copy的硬连接数为:1
copy的inode节点为:280675
copy的文件属主为:1000
copy的文件属组为:1000
copy的文件大小为:7637
copy的分配文件总块数为:16
copy的上次访问时间为:Thu May 21 19:15:49 2015
copy的上次修改时间为:Thu May 21 19:15:33 2015
copy的上次文件状态变化时间为:Thu May 21 19:15:33 2015
songxl@ubuntu:~/linuxc/manual$
获取文件的信息stat() lstat() fstat()
最新推荐文章于 2022-06-04 01:59:51 发布