news 2026/6/19 21:32:22

获取文件的属性

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
获取文件的属性

文章目录

  • 相关函数
  • stat结构体
    • st_mode判断文件类型的方法
      • 掩码方式
      • 宏方式
    • 获取访问权限
  • 例程:获取文件夹中文件的信息
  • 例程:获取文件夹下所有文件的信息
  • 在Linux系统中,我们可以使用stat、lstat和fstat函数来获取文件的属性

相关函数

  • 头文件
    • #include <sys/types.h>
    • #include <sys/stat.h>
    • #include <unistd.h>
  • 函数原型:
    • int stat(const char *path, struct stat *buf);
      • 获取路径名指向的文件的信息、文件的状态,会跟随获取符号链接文件
    • int lstat(const char *path, struct stat *buf);
      • 与stat()相同,不会跟随获取符号链接文件(如果路径名是一个符号链接,那么它将返回关于链接本身的信息,而不是链接引用的文件)
    • int fstat(int fd, struct stat *buf);
      • 与stat()相同,只是要检索的信息是由文件描述符fd指定的
  • 返回值:
    • 成功时返回0
    • 出错时返回EOF,并将errno设置为指示该错误信息

如果path是符号链接,则stat获取的是目标文件的属性,而lstat获取的是链接文件的属性

stat结构体

structstat{dev_tst_dev;//文件的设备编号ino_tst_ino;//节点mode_tst_mode;//文件的类型和存取的权限nlink_tst_nlink;//连到该文件的硬连接数目,刚建立的文件值为1uid_tst_uid;//用户IDgid_tst_gid;//组IDdev_tst_rdev;//(设备类型)若此文件为设备文件,则为其设备编号off_tst_size;//文件字节数(文件大小)unsignedlongst_blksize;//块大小(文件系统的I/O 缓冲区大小)unsignedlongst_blocks;//块数time_tst_atime;//最后一次访问时间time_tst_mtime;//最后一次修改时间time_tst_ctime;//最后一次改变时间(指属性)};

由于性能和简单性考虑,stat结构中的不同字段可能包含来自执行系统调用期间的不同时刻的状态信息。例如,如果通过调用st_mode或st_uid时,其他进程调用chmod (2)或chown (2)被更改,stat()可能会与新st_uid一起返回旧st_mode,或返回旧st_uid和新st_mode

  • 【mode_t】16位

  • 对于权限位,在哪一位置1就代表拥有哪个权限,比如6-8位置为101,表示用户对该文件具有读权限和执行权限没有写权限
  • 对于文件类型标志位,与类型掩码S_IFMT相与得到文件类型,比如0100表示目录,即S_IFDIR所代表的004

st_mode判断文件类型的方法

掩码方式

  • 第一种是掩码的方式,通过系统提供的宏来判断文件类型:
S_IFMT 0170000 文件类型的位字段的位掩码 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_IFSOCK到S_IFIFO是7种文件类型,S_IFMT是文件类型的掩码,通过和S_IFMT的与运算,可以把标识文件类型的位保留下来

宏方式

  • 第二种是使用提供的宏来判断文件类型
S_ISREG(st_mode) 0100000 是否常规文件 S_ISDIR(st_mode) 0040000 是否目录 S_ISCHR(st_mode) 0020000 是否字符设备 S_ISBLK(st_mode) 0060000 是否块设备 S_ISFIFO(st_mode) 0010000 是否FIFO文件 S_ISLNK(st_mode) 0120000 是否链接文件 S_ISSOCK(st_mode) 0140000 是否SOCKET文件

获取访问权限

  • 通过系统提供的宏来获取文件访问权限(4位掩码,第一个0表示8进制):
S_IRWXU 00700 mask for file owner permissions S_IRUSR 00400 bit:8 所有者有读权限 S_IWUSR 00200 bit:7 所有者拥有写权限 S_IXUSR 00100 bit:6 所有者拥有执行权限 S_IRWXG 00070 mask for group permissions S_IRGRP 00040 bit:5 群组拥有读权限 S_IWGRP 00020 bit:4 群组拥有写权限 S_IXGRP 00010 bit:3 群组拥有执行权限 S_IRWXO 00007 mask for permissions for others (not in group) S_IROTH 00004 bit:2 其他用户拥有读权限 S_IWOTH 00002 bit:1 其他用户拥有写权限 S_IXOTH 00001 bit:0 其他用户拥有执行权限

例程:获取文件夹中文件的信息

#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<fcntl.h>#include<time.h>intmain(intargc,constchar*argv[]){if(argc<2){printf("Usage:%s <filename>\n",argv[1]);return-1;}structstatst;#if1// 使用stat获取文件属性if(stat(argv[1],&st)==-1){perror("stat");return-1;}#elif0// 使用lstat获取文件属性if(lstat(argv[1],&st)==-1){perror("lstat");return-1;}printf("file size:%ld\n",st.st_size);#else// 使用fstat获取文件属性intfd=open(argv[1],O_RDONLY);if(fd<0){perror("open");return-1;}fstat(fd,&st);printf("file size:%ld\n",st.st_size);#endif//输出文件类型switch(S_IFMT&st.st_mode){caseS_IFREG:putchar('-');break;caseS_IFDIR:putchar('d');break;caseS_IFSOCK:putchar('s');break;caseS_IFLNK:putchar('l');break;caseS_IFBLK:putchar('b');break;caseS_IFCHR:putchar('c');break;caseS_IFIFO:putchar('f');break;default:printf("have a failed\n");return-1;}//输出当前用户对文件的权限intn=8;do{if(st.st_mode&(0x1<<n)){switch(n%3){case0:putchar('x');break;case1:putchar('w');break;case2:putchar('r');break;}}else{putchar('-');}}while(n--);//输出文件的字节大小printf("\t%ld",st.st_size);//输出文件的最后修改时间printf("\t%s",ctime(&st.st_ctime));return0;}

例程:获取文件夹下所有文件的信息

  • 获取当前文件夹内容,并显示其中文件的属性(展示效果类似于ls -al)以下面格式打印指定文件的主要信息
user@linux-mac:~$./a.out xxxdir aaa.c -rw-rw-r--635Mon Nov1117:55:242024bbb.c -rw-rw-r--151Thu Oct1710:21:252024ccc.c -rw-rw-r--972Tue Oct815:09:052024ddd.c -rw-rw-r--180Fri Oct1810:56:372024
#include<stdio.h>#include<dirent.h>#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<string.h>#include<time.h>intmain(intargc,constchar*argv[]){if(argc<2){printf("Usage: <%s> <filename>\n",argv[0]);return-1;}DIR*dirp=NULL;structdirent*dp=NULL;structstatst;chardirpath[30]="./";strcat(dirpath,argv[1]);charfilename[30]={0};intn;if((dirp=opendir(dirpath))==NULL){perror("opendir");return-1;}while((dp=readdir(dirp))!=NULL){if(!strcmp(dp->d_name,".")||!strcmp(dp->d_name,"..")){continue;}//输出文件名printf("%-30s\t",dp->d_name);// 使用lstat获取文件属性sprintf(filename,"%s%s%s",dirpath,"/",dp->d_name);if(lstat(filename,&st)==-1){perror("lstat");return-1;}//输出文件类型switch(S_IFMT&st.st_mode){caseS_IFREG:putchar('-');break;caseS_IFDIR:putchar('d');break;caseS_IFLNK:putchar('l');break;caseS_IFSOCK:putchar('s');break;caseS_IFBLK:putchar('b');break;caseS_IFCHR:putchar('c');break;caseS_IFIFO:putchar('f');}//输出当前用户对文件的权限n=8;do{if(st.st_mode&(0x1<<n)){switch(n%3){case0:putchar('x');break;case1:putchar('w');break;case2:putchar('r');break;}}else{putchar('-');}}while(n--);//输出文件的字节大小printf("\t%10ld",st.st_size);//输出文件的最后修改时间printf("\t%30s",ctime(&st.st_ctime));}closedir(dirp);return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/18 1:51:20

springboot_ssm超市在线配送管理系统java论文

目录具体实现截图系统所用技术介绍写作提纲核心代码部分展示结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 springboot_ssm超市在线配送管理系统java论文 系统所用技术介绍 本毕业设计项目基于B/S结构模式&am…

作者头像 李华
网站建设 2026/6/16 5:46:01

springboot_ssm足球联赛管理系统 商城_tdl2g--论文

目录具体实现截图系统所用技术介绍写作提纲核心代码部分展示结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 springboot_ssm足球联赛管理系统 商城_tdl2g–论文 系统所用技术介绍 本毕业设计项目基于B/S结构模式…

作者头像 李华
网站建设 2026/6/13 8:28:02

License服务器搭建:企业级授权管理体系设计

License服务器搭建&#xff1a;企业级授权管理体系设计 在大型AI平台的实际运维中&#xff0c;一个常被低估但极具破坏力的问题正在浮现&#xff1a;明明采购了20个TensorRT企业版License&#xff0c;却总有团队反馈“授权不足”&#xff0c;而另一些节点上的License却整日闲置…

作者头像 李华
网站建设 2026/6/18 1:48:47

孩子近视防控,哪些方法最容易坚持?

在儿童青少年近视高发的当下&#xff0c;防控工作的关键不仅在于方法的有效性&#xff0c;更在于能否长期坚持。很多家长尝试过多种防控手段&#xff0c;却因操作复杂、占用时间过多等问题难以持续。结合孩子的学习生活节奏&#xff0c;找到简单易行、可融入日常的防控方法&…

作者头像 李华