Linux获取文件属性

以-rw-rw-r-- 1 ubuntu ubuntu 56 八月 1 19:37 1.txt 为例

一、stat函数

功能:获取文件的属性

函数原型:

cpp 复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *pathname, struct stat *statbuf);

参数:

char *pathname:指定要获取属性的文件路径以及名字

struct stat *statbuf:存储获取到的属性

返回值:

成功,返回0

失败,返回-1,更新errno

在Linux中封装的结构体:

cpp 复制代码
 struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */             inode号
               mode_t    st_mode;        /* File type and mode */       文件类型以及权限
               nlink_t   st_nlink;       /* Number of hard links */     硬链接数
               uid_t     st_uid;         /* User ID of owner */         用户uid
               gid_t     st_gid;         /* Group ID of owner */        组用户gid
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */     文件大小
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* Time of last access */     最后一次被访问的时间
               struct timespec st_mtim;  /* Time of last modification */     最后一次被修改的时间
               struct timespec st_ctim;  /* Time of last status change */     最后一次改变状态的时间

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec    
           #define st_ctime st_ctim.tv_sec
           };

打印文件属性:

cpp 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	struct stat buf;
	if(stat("./1.txt",&buf) < 0)
	{
		perror("stat");
		return -1;
	}
	//获取文件类型和权限
	printf("0%o ",buf.st_mode);

	//获取文件的硬链接数
	printf("%ld ",buf.st_nlink);

	//获取文件所属用户
	printf("%d ",buf.st_uid);
	
	//获取文件所属组用户
	printf("%d ",buf.st_gid);

	//获取文件大小
	printf("%ld ",buf.st_size);

	//获取时间戳
	printf("%ld ",buf.st_ctime);
	return 0;
}

【输出样例】0100664 1 1000 1000 56 1690889850

使用stat函数输出的结果与Linux定义的文件属性输出样式有些不同,因此还需要进行一些处理

二、获取文件权限

cpp 复制代码
void get_filePermission(mode_t m)
{
	long x = 0400;
	char c[]="rwx";
	int count = 0; 
	while(x)
	{
		if((m & x) == 0)
			putchar('-');
		else
			printf("%c",c[count%3]);
		count++;
		x = x >> 1;
	}
	putchar(' ');
}

三、获取文件类型

cpp 复制代码
void get_fileType(mode_t m)
{
	if(S_ISREG(m))
		putchar('-');
	else if(S_ISDIR(m))
		putchar('d');
	else if(S_ISCHR(m))
		putchar('c');
	else if( S_ISBLK(m))
		putchar('b');
	else if( S_ISFIFO(m))
		putchar('p');
	else if( S_ISLNK(m))
		putchar('l');
	else if( S_ISSOCK(m))
		putchar('s');
}

四、获取文件所属用户名

getpwuid函数

功能:通过uid号获取用户的信息

函数原型:

cpp 复制代码
#include <sys/types.h>
#include <pwd.h>

struct passwd *getpwuid(uid_t uid);

参数:

uid_t uid:指定uid号

返回值:

成功,返回结构体指针

失败,返回NULL,更新errno

在Linux中封装的结构体:

cpp 复制代码
struct passwd {
    char   *pw_name;       /* username */
    char   *pw_passwd;     /* user password */
    uid_t   pw_uid;        /* user ID */
    gid_t   pw_gid;        /* group ID */
    char   *pw_gecos;      /* user information */
    char   *pw_dir;        /* home directory */
    char   *pw_shell;      /* shell program */
};

封装的函数:

cpp 复制代码
void get_fileUserName(uid_t uid)
{
    struct passwd *pwd = getpwuid(uid);
    if(NULL == pwd)
    {
        perror("getpwuid");
        return;
    }
    printf("%s\n",pwd->pw_name);
    return;
}

五、获取文件所属组用户名

getgrgid函数

功能:通过gid号获取组用户的信息

函数原型:

cpp 复制代码
#include <sys/types.h>
#include <grp.h>

struct group *getgrgid(gid_t gid);

参数:

gid_t gid:指定gid号

返回值:

成功,返回结构体指针

失败,返回NULL,更新errno

封装的函数:

cpp 复制代码
void get_fileGrpName(gid_t gid)
{
    struct group *grp = getgrgid(gid);
    if(NULL == grp)
    {
        perror("getgrgid");
        return;
    }
    printf("%s\n",grp->gr_name);
    return;
}

六、完整代码演示

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
void get_fileType(mode_t m)
{
	if(S_ISREG(m))
		putchar('-');
	else if(S_ISDIR(m))
		putchar('d');
	else if(S_ISCHR(m))
		putchar('c');
	else if( S_ISBLK(m))
		putchar('b');
	else if( S_ISFIFO(m))
		putchar('p');
	else if( S_ISLNK(m))
		putchar('l');
	else if( S_ISSOCK(m))
		putchar('s');
}
void get_filePermission(mode_t m)
{
	long x = 0400;
	char c[]="rwx";
	int count = 0; 
	while(x)
	{
		if((m & x) == 0)
			putchar('-');
		else
			printf("%c",c[count%3]);
		count++;
		x = x >> 1;
	}
	putchar(' ');
}
int main(int argc, const char *argv[])
{
	struct stat buf;
	if(stat("./1.txt",&buf) < 0)
	{
		perror("stat");
		return -1;
	}
	//获取文件类型和权限
//	printf("0%o ",buf.st_mode);
	get_fileType(buf.st_mode);
	get_filePermission(buf.st_mode);

	//获取文件的硬链接数
	printf("%ld ",buf.st_nlink);

	//获取文件所属用户
//	printf("%d ",buf.st_uid);
	struct passwd *uid = getpwuid(buf.st_uid);
	printf("%s ",uid->pw_name);
	
	//获取文件所属组用户
//	printf("%d ",buf.st_gid);
	struct group *gid = getgrgid(buf.st_gid);
	printf("%s ",gid->gr_name);

	//获取文件大小
	printf("%ld ",buf.st_size);

	//获取时间戳
	struct tm *info=NULL;
	info = localtime(&buf.st_mtime);
//	printf("%ld ",buf.st_ctime);
	printf("%02d %02d %02d:%02d ",info->tm_mon+1,info->tm_mday,info->tm_hour,info->tm_min);
	printf("1.txt\n");
	return 0;
}
相关推荐
殷色玫瑰14 小时前
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理
java·linux·c语言·c++
IT_陈寒15 小时前
SpringBoot自动配置坑了我一把,原来是这样绕过去的
前端·人工智能·后端
广州华水科技15 小时前
单北斗GNSS变形监测在大坝安全监测中的应用与优势
前端
꯭自꯭闭꯭15 小时前
DM7主备升级方案
linux·服务器·数据库
用户41071920132515 小时前
VMware 虚拟机Ubuntu 环境linux远程连接失败
linux
zeng不错15 小时前
B站 173 个投稿活动看到眼瞎?我写了个扩展,主打一个精准打击
前端
Latchh15 小时前
前端导出的JPEG红字发糊,质量要拉到100才清楚
前端·图像处理·人工智能·计算机视觉
lisanmengmeng15 小时前
Nagios邮件报警的配置
linux·运维·服务器
Ruiery16 小时前
Linux 6.6内核 CPU 深度解析(六):cpufreq
linux·运维·服务器
默_笙16 小时前
🚦 请三个 AI 考官给 RAG 打分:量化评估实战(下)
前端·javascript