目录
1. 前言
2. 函数介绍
2.1 访问目录 – opendir
2.2 访问目录 – readdir
2.3 访问目录 – closedir
2.4 修改文件访问权限 – chmod/fchmod
2.5 获取文件属性 – stat/lstat/fstat
2.5.1 文件属性 – struct stat
2.6 文件类型 – st_mode
3. 代码练习
3.1 要求
3.2 代码实现
3.2.1 依赖库文件
3.2.2 声明子函数
3.2.3 实现子函数
3.2.4 main函数实现
5. 总结
1. 前言
本文通过介绍文件目录以及文件属性相关函数进行目录操作和文件属性获取。
2. 函数介绍
2.1 访问目录 – opendir
opendir函数用来打开一个目录文件:
#include <dirent.h>DIR *opendir(const char *name);DIR *fdopendir(int fd); 使用文件描述符,要配合open函数使用
- DIR是用来描述一个打开的目录文件的结构体类型
- 成功时返回目录流指针;出错时返回NULL
2.2 访问目录 – readdir
readdir函数用来读取目录流中的内容:
#include <dirent.h>struct dirent *readdir(DIR *dirp);
- struct dirent是用来描述目录流中一个目录项的结构体类型
- 包含成员char d_name[256] 参考帮助文档
- 成功时返回目录流dirp中下一个目录项;
- 出错或到末尾时时返回NULL
2.3 访问目录 – closedir
closedir函数用来关闭一个目录文件:
#include <dirent.h>int closedir(DIR *dirp);
- 成功时返回0;出错时返回EOF
2.4 修改文件访问权限 – chmod/fchmod
chmod/fchmod函数用来修改文件的访问权限:
#include <sys/stat.h>int chmod(const char *path, mode_t mode);int fchmod(int fd, mode_t mode);
- 成功时返回0;出错时返回EOF
- root和文件所有者能修改文件的访问权限
- 示例: chmod(“test.txt”, 0666);
2.5 获取文件属性 – stat/lstat/fstat
stat/lstat/fstat函数用来获取文件属性:
#include <sys/stat.h>int stat(const char *path, struct stat *buf);int lstat(const char *path, struct stat *buf);int fstat(int fd, struct stat *buf);
- 成功时返回0;出错时返回EOF
- 如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性
2.5.1 文件属性 – struct stat
struct stat是存放文件属性的结构体类型:
struct stat {dev_t st_dev; //文件的设备编号ino_t st_ino; //节点mode_t st_mode; //文件的类型和存取的权限nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1uid_t st_uid; //用户IDgid_t st_gid; //组IDdev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号off_t st_size; //文件字节数(文件大小)unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)unsigned long st_blocks; //块数time_t st_atime; //最后一次访问时间time_t st_mtime; //最后一次修改时间time_t st_ctime; //最后一次改变时间(指属性)
};
2.6 文件类型 – st_mode
通过系统提供的宏来判断文件类型:
S_ISREG(st_mode) | 是否常规文件 |
S_ISDIR(st_mode) | 是否目录 |
S_ISCHR(st_mode) | 是否字符设备 |
S_ISBLK(st_mode) | 是否块设备 |
S_ISFIFO(st_mode) | 是否FIFO文件 |
S_ISLNK(st_mode) | 是否链接文件 |
S_ISSOCK(st_mode) | 是否SOCKET文件 |
通过系统提供的宏来获取文件访问权限:
S_IRUSR | 所有者有读权限 |
S_IWUSR | 所有者拥有写权限 |
S_IXUSR | 所有者拥有执行权限 |
S_IRGRP | 群组拥有读权限 |
S_IWGRP | 群组拥有写权限 |
S_IXGRP | 群组拥有执行权限 |
S_IROTH | 其他用户拥有读权限 |
S_IWOTH | 其他用户拥有写权限 |
S_IXOTH | 其他用户拥有执行权限 |
3. 代码练习
3.1 要求
遍历一个文件夹下所有文件,并打印文件大小和日期
3.2 代码实现
3.2.1 依赖库文件
#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
3.2.2 声明子函数
void ReadDir(DIR* dp);
3.2.3 实现子函数
若读到的目录项为"."或".."则跳过;
判定是否为常规文件,若是,则打印文件大小和日期。
注意:这里的stat若打开除程序允许目录的其他文件夹中的文件,其中path变量不能只是当前目录下的文件名,那样会出现未找到文件或者目录的错误,应该是文件的绝对路径。
void ReadDir(DIR* dp)
{struct dirent *dt;int ret;while((dt = readdir(dp))!=NULL){struct stat buf;if((strcmp(dt->d_name,"..")!=0)&&(strcmp(dt->d_name,".")!=0)){printf("%s",dt->d_name);}ret = stat(dt->d_name,&buf);if(ret<0){perror("stat");return;}if(S_ISREG(buf.st_mode)){printf(" %d",(int)buf.st_size);struct tm* t;t = localtime(&buf.st_ctime);printf(" %d-%d-%d %d:%d\n",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);}else{printf("\n");}}return;
}
3.2.4 main函数实现
int main(int argc,char* argv[])
{DIR* dp;struct dirent *dt;dp = opendir("/home/linux/Lv5/Day9/");if(dp == NULL){perror("opendir");return 0;}ReadDir(dp);closedir(dp);return 0;
}
4. 测试
5. 总结
本文介绍了文件目录以及文件属性相关函数,并通过代码练习实现了目录和文件属性获取。