博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Linux编程-stat

Posted on 2023-03-14 07:05  乔55  阅读(17)  评论(0编辑  收藏  举报

struct stat结构体成员

struct stat{
	dev_t st_dev;	        // 文件的设备编号 
	ino_t st_ino;	        // inode
	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;		// 文件字节数
	blisize_t st_blksize;	// 块大小
	blkcnt_t st_blocks;	// 块数
	time_t st_atime;	// 最后一次访问时间
	time_t st_mtime;	// 最后一次修改时间
	time_t st_ctime;	// 最后一次改变时间(指改变属性) 
};

mode_t st_mode 位图

// 0-2位 
S_IRWXO     00007   // 掩码,过滤st_mode中除其他人权限以外的信息 
S_IROTH     00004   // 其他人读权限 
S_IWOTH     00002   // 其他人写权限 
S_IXOTH     00001   // 其他人执行权限 

// 3-5位 
S_IRWXG     00070   // 掩码,过滤st_mode中除所属组权限以外的信息  
S_IRGRP     00040   // 所属组读权限 
S_IWGRP     00020   // 所属组写权限  
S_IXGRP     00010   // 所属组执行权限 

// 6-8位 
S_IRWXU     00070   // 掩码,过滤st_mode中除文件所有者权限以外的信息  
S_IRUSR     00040   // 文件所有者读权限 
S_IWUSR     00020   // 文件所有者写权限  
S_IXUSR     00010   // 文件所有者执行权限

if(st_mode & S_IRUSR) // 为true表明可读
if(st_mode & S_IWUSR) // 为true表明可写 
if(st_mode & S_IXUSR) // 为true表明可执行 

// 12-15位,文件类型

S_IFMT     0170000   // 掩码,过滤st_mode中除文件类型以外的信息 
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_ISREG(m)  is it a regular file?
S_ISDIR(m)  directory?
S_ISCHR(m)  character device?
S_ISBLK(m)  block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)
S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)


if(st_mode & S_IFMT) == S_IFREG) // 为true,表明是普通文件 
if(S_ISREG(st_mode)) 		 // 为true,表明是普通文件 
if(S_ISDIR(st.st_mode)) 	 // 为tree,表明是目录文件 
 

stat函数详解

int stat(const char *pathname, struct stat *buf);
// 穿透函数:操作软链接时,操作的是软链接指向的文件
// 类似的,cat mys,同样会穿透符号软件,cat的是符号链接mys指向的文件
// path:只读路径
// buf:传出参数
// 成功返回0,失败返回-1

fstat函数详解

int fstat(int fd, struct stat *buf);

lstat函数详解

int lstat(const char *pathname, struct stat *buf);
// 功能与stat一样,除了在操作软链接时不同,它操作的是软链接本身

stat结构体成员变量

access详解

int access(const char *pathname, int mode);
// 测试文件是否有某权限,是否存在
// R_OK,W_OK,X_OK,F_OK

lstat获取文件信息

// 用stat获取文件大小是比较正规的用法
// 用lseek方法获取文件大小是偏门
void test(const char* str)
{
        struct stat buf;
        int ret = lstat(str, &buf);
        if(ret == -1)
        {
                perror("stat failed:");
                exit(1);
        }

        // 获取文件大小
        int size = (int)buf.st_size;
        printf("size = %d\n", size);

        // 获取文件类型
        if(S_ISREG(buf.st_mode))
        {
                printf("是普通文件,");
        }
        else if(S_ISDIR(buf.st_mode))
        {
                printf("是目录文件,");
        }
        else if(S_ISCHR(buf.st_mode))
        {
                printf("是字符文件,");
        }
        else if(S_ISBLK(buf.st_mode))
        {
                printf("是块文件,");
        }
        else if(S_ISFIFO(buf.st_mode))
        {
                printf("是管道文件,");
        }
        else if(S_ISLNK(buf.st_mode))
        {
                printf("是符号链接文件,");
        }
        else if(S_ISSOCK(buf.st_mode))
        {
                printf("是套接字文件,");
        }

        // 获取文件权限
        if(buf.st_mode & S_IRUSR)
        {
                printf("所有者权限是可读,");
        }
        if(buf.st_mode & S_IWUSR)
        {
                printf("所有者权限是可写,");
        }
        if(buf.st_mode & S_IXUSR)
        {
                printf("所有者权限是可执行");
        }
    printf("\n");
}

int main(int argc, char** argv)
{
        if(argc < 2)
        {
                perror("usage:./mytarget fileName");
                exit(1);
        }
        test(argv[1]);
        return 0;
}

举例:获取文件类型

static int ftype(const char* fname)
{
	struct stat st;
	if(stat(fname, &st) < 0)
	{
		perror("stat()");
		exit(1);
	}
	if(S_ISREG(st.st_mode))
	{
		return '-';
	}
	else if(S_ISDIR(st.st_mode))
	{
		return 'd';
	}
	else if(S_ISCHR(st.st_mode))
	{
		return 'c';
	}
	else if(S_ISBLK(st.st_mode))
	{
		return 'b';
	}
	else if(S_ISFIFO(st.st_mode))
	{
		return 'f';
	}
	else if(S_ISLNK(st.st_mode))
	{
		return 'l';
	}
	else if(S_ISSOCK(st.st_mode))
	{
		return 's';
	}
	else
	{
		return '?';
	}
}
int main(int argc, char** argv)
{
	if(argc < 2)
	{
		fprintf(stderr, "usage...\n");
		exit(1);
	}

	printf("%c\n", ftype(argv[1]));

	return 0;
}