Linux(四)函数获知文件、目录的属性、权限

您所在的位置:网站首页 linux系统查看权限 Linux(四)函数获知文件、目录的属性、权限

Linux(四)函数获知文件、目录的属性、权限

2024-01-21 16:18| 来源: 网络整理| 查看: 265

Linux(四)函数获知文件、目录的属性、权限

ubuntu下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLQB8zVb-1641384335348)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20211212180944079.png)]

用函数判断文件的权限、类型,需要用到上图所示的宏常量,这些宏定义在C语言库里,我们可以直接使用这些宏。

一、获取文件属性 1.1 stat

函数功能:通过文件名(带路径)获取文件属性(节点号、文件类型、链接数、属主 ID、文件大小等 )

函数原型:int stat(const char *path,struct stat *buf)

头文件:#include、#include、#include

参数:const char *path: 带路径的文件名,

​ struct stat *buf :文件属性结构体变量的地址

struct stat { dev_t st_dev; /*如果是设备,返回设备表述符,否则为 0*/ ino_t st_ino; /* i 节点号 */ mode_t mode st_mode; /* 文件类型 */ nlink_t st_nlink; /* 链接数 */ uid_t st_uid; /* 属主 ID */ gid_t st_gid; /* 组 ID */ dev_t st_rdev; /* 设备类型*/ off_t st_size; /* 文件大小,字节表示 */ blksize_t st_blksize; /* 系统每次按块Io操作时块的大小(一般是512或1024)*/ blkcnt_t st_blocks; /*块的索引号 */ time_t st_atime; /* 最后访问时间,如read*/ time_t st_mtime; /* 最后修改时间*/ time_t st_ctime; /*显示的是文件的权限、拥有者、所属的组、链接数发生改变时的时间。当然当内容改变时也会随之改变 */ };

返回值:成功返回0,失败返回-1

示例代码:通过stat函数 获取文件 属性 模仿ls -ail 的功能

#include #include #include #include #include #include #include struct stat buf; int main(int argv,char* argc[]) { char fileProperty[11]={'-','-','-','-','-','-','-','-','-','-','\0'}; //存储文件类型(第1个字节)和读写权限(后9个字节) unsigned long nlink; //链接数 stat(argc[1],&buf); /*获取文件的类型*/ switch ((buf.st_mode&S_IFMT)) { case S_IFSOCK: fileProperty[0] = 's'; break;//套节字文件(s) case S_IFREG: fileProperty[0] = '-'; break;//普通文件(-) case S_IFLNK: fileProperty[0] = 'l'; break;//链接文件(l) case S_IFCHR: fileProperty[0] = 'c'; break;//字符设备文件(c) case S_IFIFO: fileProperty[0] = 'p'; break;//管道文件(p) case S_IFDIR: fileProperty[0] = 'd'; break;//目录文件(d) case S_IFBLK: fileProperty[0] = 'b'; break;//块设备文件(b) default: break; } /*获取文件的读写权限*/ char i = 1; unsigned int off = 256; for (char j = 0; j case S_IRUSR: fileProperty[1] = 'r'; break;//文件所属用户 case S_IWUSR: fileProperty[2] = 'w'; break;//文件所属用户 case S_IXUSR: fileProperty[3] = 'x'; break;//文件所属用户 case S_IRGRP: fileProperty[4] = 'r'; break;//组用户 case S_IWGRP: fileProperty[5] = 'w'; break;//组用户 case S_IXGRP: fileProperty[4] = 'x'; break;//组用户 case S_IROTH: fileProperty[7] = 'r'; break;//其他用户 case S_IWOTH: fileProperty[8] = 'w'; break;//其他用户 case S_IXOTH: fileProperty[9] = 'x'; break;//其他用户 default: break; } } /*获取链接数*/ nlink = buf.st_nlink; /*通过文件所属的用户ID,获取文件所属用户名*/ //获取到 user_id, group_id, 调用 getpwuid/getgrgid 即可 struct passwd * user = NULL; struct group * group = NULL; user = getpwuid(buf.st_uid); group = getgrgid(buf.st_gid); /*获取文件大小*/ unsigned long fileSize; fileSize = buf.st_size; /*获取最近修改时间*/ struct tm *loTim = NULL; loTim = localtime(&buf.st_ctime); /*******输出文件属性信息********/ printf("%lu %s %lu %s %s %lu %d年%02d月%02d日 %02d:%02d:%02d %s\n",buf.st_ino,fileProperty,nlink,user->pw_name,group->gr_name,fileSize,loTim->tm_year + 1900,loTim->tm_mon+1,loTim->tm_mday,loTim->tm_hour,loTim->tm_min,loTim->tm_sec,argc[1]); return 0; } 1.2 fstat

函数功能:通过文件描述符获取文件属性(节点号、文件类型、链接数、属主 ID、文件大小等 ),需要打开文件获取文件描述符,用法与stat类似

函数原型:int fstat(int fds,struct stat *buf);

头文件:#include、#include、#include

参数:int fds : 文件描述符

​ struct stat *buf : 文件属性结构体变量的地址

返回值:成功返回0,失败返回-1

#include #include #include #include #include #include #include #include struct stat buf; int main(int argv,char* argc[]) { char fileProperty[11]={'-','-','-','-','-','-','-','-','-','-','\0'}; //存储文件类型(第1个字节)和读写权限(后9个字节) unsigned long nlink; //链接数 int fd; fd = open(argc[1],O_RDONLY); // stat(argc[1],&buf); fstat(fd,&buf); /*获取文件的类型*/ switch ((buf.st_mode&S_IFMT)) { case S_IFSOCK: fileProperty[0] = 's'; break;//套节字文件(s) case S_IFREG: fileProperty[0] = '-'; break;//普通文件(-) case S_IFLNK: fileProperty[0] = 'l'; break;//链接文件(l) case S_IFCHR: fileProperty[0] = 'c'; break;//字符设备文件(c) case S_IFIFO: fileProperty[0] = 'p'; break;//管道文件(p) case S_IFDIR: fileProperty[0] = 'd'; break;//目录文件(d) case S_IFBLK: fileProperty[0] = 'b'; break;//块设备文件(b) default: break; } /*获取文件的读写权限*/ char i = 1; unsigned int off = 256; for (char j = 0; j case S_IRUSR: fileProperty[1] = 'r'; break; case S_IWUSR: fileProperty[2] = 'w'; break; case S_IXUSR: fileProperty[3] = 'x'; break; case S_IRGRP: fileProperty[4] = 'r'; break; case S_IWGRP: fileProperty[5] = 'w'; break; case S_IXGRP: fileProperty[4] = 'x'; break; case S_IROTH: fileProperty[7] = 'r'; break; case S_IWOTH: fileProperty[8] = 'w'; break; case S_IXOTH: fileProperty[9] = 'x'; break; default: break; } } /*获取链接数*/ nlink = buf.st_nlink; /*通过文件所属的用户ID,获取文件所属用户名*/ //获取到 user_id, group_id, 调用 getpwuid/getgrgid 即可 struct passwd * user = NULL; struct group * group = NULL; user = getpwuid(buf.st_uid); group = getgrgid(buf.st_gid); /*获取文件大小*/ unsigned long fileSize; fileSize = buf.st_size; /*获取最近修改时间*/ // char* localTime = ctime(buf.st_ctime); /*******输出文件属性信息********/ struct tm *loTim = NULL; loTim = localtime(&buf.st_ctime); printf("%lu %s %lu %s %s %lu %d年%02d月%02d日 %02d:%02d:%02d %s\n",buf.st_ino,fileProperty,nlink,user->pw_name,group->gr_name,fileSize,loTim->tm_year + 1900,loTim->tm_mon+1,loTim->tm_mday,loTim->tm_hour,loTim->tm_min,loTim->tm_sec,argc[1]); return 0; } 1.3 lstat

函数功能:获取的是链接文件的文件属性(节点号、文件类型、链接数、属主 ID、文件大小等 ),需要打开文件获取文件描述符,用法与stat类似

函数原型:int lstat(const char *path,struct stat *buf);

头文件:#include、#include、#include

参数:const char *path : 文件名(含路径)

​ struct stat *buf : 文件属性结构体变量的地址

返回值:成功返回0,失败返回-1

示例:

#include #include #include #include #include #include #include #include struct stat buf; int main(int argv,char* argc[]) { char fileProperty[11]={'-','-','-','-','-','-','-','-','-','-','\0'}; //存储文件类型(第1个字节)和读写权限(后9个字节) unsigned long nlink; //链接数 int fd; // fd = open(argc[1],O_RDONLY); // stat(argc[1],&buf); // fstat(fd,&buf); lstat(argc[1],&buf); /*获取文件的类型*/ switch ((buf.st_mode&S_IFMT)) { case S_IFSOCK: fileProperty[0] = 's'; break;//套节字文件(s) case S_IFREG: fileProperty[0] = '-'; break;//普通文件(-) case S_IFLNK: fileProperty[0] = 'l'; break;//链接文件(l) case S_IFCHR: fileProperty[0] = 'c'; break;//字符设备文件(c) case S_IFIFO: fileProperty[0] = 'p'; break;//管道文件(p) case S_IFDIR: fileProperty[0] = 'd'; break;//目录文件(d) case S_IFBLK: fileProperty[0] = 'b'; break;//块设备文件(b) default: break; } /*获取文件的读写权限*/ char i = 1; unsigned int off = 256; for (char j = 0; j case S_IRUSR: fileProperty[1] = 'r'; break; case S_IWUSR: fileProperty[2] = 'w'; break; case S_IXUSR: fileProperty[3] = 'x'; break; case S_IRGRP: fileProperty[4] = 'r'; break; case S_IWGRP: fileProperty[5] = 'w'; break; case S_IXGRP: fileProperty[4] = 'x'; break; case S_IROTH: fileProperty[7] = 'r'; break; case S_IWOTH: fileProperty[8] = 'w'; break; case S_IXOTH: fileProperty[9] = 'x'; break; default: break; } } /*获取链接数*/ nlink = buf.st_nlink; /*通过文件所属的用户ID,获取文件所属用户名*/ //获取到 user_id, group_id, 调用 getpwuid/getgrgid 即可 struct passwd * user = NULL; struct group * group = NULL; user = getpwuid(buf.st_uid); group = getgrgid(buf.st_gid); /*获取文件大小*/ unsigned long fileSize; fileSize = buf.st_size; /*获取最近修改时间*/ // char* localTime = ctime(buf.st_ctime); /*******输出文件属性信息********/ struct tm *loTim = NULL; loTim = localtime(&buf.st_ctime); printf("%lu %s %lu %s %s %lu %d年%02d月%02d日 %02d:%02d:%02d %s\n",buf.st_ino,fileProperty,nlink,user->pw_name,group->gr_name,fileSize,loTim->tm_year + 1900,loTim->tm_mon+1,loTim->tm_mday,loTim->tm_hour,loTim->tm_min,loTim->tm_sec,argc[1]); return 0; }

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7cX3l4ve-1641384335350)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20220102223203662.png)]

stat 和 fstat的差别:stat通过文件名获取文件属性(不需要打开文件),fstat通过文件描述符获取属性(需要打开文件) stat 和 lstat的区别:stat获取文件的属性的时候获取的是链接文件所指向的文件的属性,lstat获取的是链接文件的属性 通过shell指令获取文件属性 ls -ail ls 命令实际上就是调用stat等系统调用的函数读取文件属性并显示出来 1.4 access

函数功能:检测当前用户(运行这个程序的用户)对该文件是否有某权限

函数原型:int access(const char *pathname, int mode);

头文件:#include

参数:const char *pathname : 文件名(含路径)

​ int mode:权限类型,可组合使用

​ R_OK:测试读权限

W_OK:测试写权限 X_OK:测试执行权限

​ F_OK:测试文件是否存在 : 文件属性结构体变量的地址

返回值:成功返回0,失败返回-1

示例:

#include #include int main(int argv,char* argc[]) { int status; status = access(argc[1],R_OK); if (status printf("有读权限\n"); } return 0; }

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ba6Dd5uJ-1641384335352)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20220103001827134.png)]

二、目录操作 2.1 mkdir

函数功能:创建目录文件(不能一次创建多级目录)

函数原型:int mkdir(const char *pathname, mode_t mode);

头文件:#include、#include

参数:const char *pathname: 文件名(含路径)

​ mode: 文件权限用数字或宏表示

返回值:成功返回0,失败返回-1

示例:

#include #include #include #define U8 unsigned char int main(void) { U8 status; status = mkdir("dir1",0664); if (status U8 status; status = rmdir("dir1"); if (status U8 status; char buf[255]; char *pwd = NULL; pwd = getcwd(buf,255); if (NULL == pwd) { perror("getcwd"); } printf("当前路径: %s\n",buf); return 0; }

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-you2MwmC-1641384335355)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20220103201025484.png)]

2.4 get_current_dir_name

函数功能:获取当前所在路径 (注意:使用时要在第一行加上#define _GNU_SOURCE)

函数原型:char *get_current_dir_name(void);

头文件:#include

参数: 无

返回值:成功返回路径,失败返回NULL

#define _GNU_SOURCE #include #include #define U8 unsigned char int main(void) { U8 status; char *pwd = NULL; pwd = get_current_dir_name(); if (NULL == pwd) { perror("getcwd"); } printf("当前路径: %s\n",pwd); return 0; }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixURy2Fk-1641384335356)(C:\Users\纵横四海\AppData\Roaming\Typora\typora-user-images\image-20220103201939480.png)]

2.5 chmod

功能:更改文件权限

函数原型:int chmod(const char *path, mode_t mode);

所属头文件: #include

#include

参数:path:文件路径

​ mode:权限

返回值:成功返回0,失败返回-1

#include #include #include int main() { char status; status = chmod("test.txt",0666); if (status void *__fd; /* `struct hurd_fd' pointer for descriptor. */ char *__data; /* Directory block. */ int __entry_data; /* Entry number `__data' corresponds to. */ char *__ptr; /* Current pointer into the block. */ int __entry_ptr; /* Entry number `__ptr' corresponds to. */ size_t __allocation; /* Space allocated for the block. */ size_t __size; /* Total valid data in the block. */ __libc_lock_define (, __lock) /* Mutex lock for this structure. */ }; 2.7 closedir (和 文件关闭函数close、fclose类似)

函数功能:关闭目录

函数头文件:

\#include \#include

函数原型:int closedir(DIR *dir);

函数参数: DIR *dir:目录流指针

函数返回值:成功返回0 ,失败返回-1

2.8 readdir (和 文件读函数 read、fread类似)

函数功能: 读取目录文件,目录中的文件信息(文件名、扩展名等等)

函数头文件:

\#include \#include

函数原型: struct dirent *readdir(DIR *dirp);

函数参数: DIR *dirp:目录流指针

函数返回值:成功返回:指向存放目录相关信息的结构体指针 , 失败:返回NULL

struct dirent结构体 // 存储目录中的文件信息(文件名、扩展名等等) #include struct dirent { long d_ino; /* inode number 索引节点号 */ off_t d_off; /* offset to this dirent 在目录文件中的偏移 */ unsigned short d_reclen; /* length of this d_name 文件名长 */ unsigned char d_type; /* the type of d_name 文件类型 */ char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */ }

2.6、2.7、2.8 示例代码:

#include #include #include int main() { char status; DIR* mydir; struct dirent * mydirent; mydir = opendir("test"); if (NULL == mydir) { perror("opendir"); } // mydirent = readdir(mydir); while ((mydirent = readdir(mydir)) != NULL) { printf("索引节点号: %lu\n",mydirent->d_ino); printf("在目路文件中的偏移: %ld\n",mydirent->d_off); printf("文件名长度: %d\n",mydirent->d_reclen); printf("文件类型: %d\n",mydirent->d_type); printf("文件名: %s\n",mydirent->d_name); printf("**************************************\n"); } status = closedir(mydir); if (status char status; DIR* mydir = NULL; struct dirent * mydirent = NULL; mydir = opendir("./test"); if (NULL == mydir) { perror("opendir"); } // mydirent = readdir(mydir); while ((mydirent = readdir(mydir)) != NULL) { printf("索引节点号: %lu\n",mydirent->d_ino); printf("在目路文件中的偏移: %ld\n",mydirent->d_off); printf("文件名长度: %d\n",mydirent->d_reclen); printf("文件类型: %d\n",mydirent->d_type); printf("文件名: %s\n",mydirent->d_name); printf("**************************************\n"); } rewinddir(mydir); printf("使用rewinddir之后,目录指针指向目录文件开头\n"); while ((mydirent = readdir(mydir)) != NULL) { printf("索引节点号: %lu\n",mydirent->d_ino); printf("在目路文件中的偏移: %ld\n",mydirent->d_off); printf("文件名长度: %d\n",mydirent->d_reclen); printf("文件类型: %d\n",mydirent->d_type); printf("文件名: %s\n",mydirent->d_name); printf("*************************\n"); } status = closedir(mydir); if (status


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3