学习重点:
1.目录I/O的函数接口
2.目录的遍历,目录的递归遍历
1.【mkdir】
1.1函数原型
【int mkdir(const char *pathname, mode_t mode);】
1.2函数功能
创建目录文件
1.3函数参数
1.3.1【pathname】
文件路径
1.3.2【mode】
文件的权限
1.4返回值
【成功】:返回0
【失败】:返回-1
1.5源码示例
(1)多次执行效果为覆盖
2.【rmdir】
2.1函数原型
【int rmdir(const char *pathname);】
2.2函数功能
删除空目录文件
2.3函数参数
2.4返回值
【成功】:返回0
【失败】:返回-1
3.【opendir】
3.1函数原型
【DIR *opendir(const char *name);】
3.2函数功能
打开目录获得目录流指针
3.3函数参数
3.3.1【name】
目录文件路径
3.4返回值
【成功】:返回目录流指针
【失败】:返回NULL
目录流数据结构:
typedef struct{
int fd; /*目录文件的文件描述符*/
struct dirent *dirent; /*当前读取的目录项*/
}DIR;
说明:
【fd】:是目录文件的文件描述符。
【dirent】:字段是一个指向当前读取的目录项的指针。
目录流的底层实现是通过文件描述符和目录缓存来实现的。当用户调用【opendir】函数打开一个目录时,系统会创建一个文件描述符,然后将目录文件映射到该文件描述符上,并创建一个目录缓存,用于存储读取的目录项。每次调用【readdir】函数,系统会从目录缓存中读取一个目录项,并将【dirent】 指针指向该目录项。当读取完所有的目录项后,系统会关闭文件描述符,并释放目录缓存。
用户不能直接访问其内部结构,而是通过 【opendir】函数打开目录,并通过【readdir】函数读取目录项。在使用完【DIR】数据结构后,用户应该调用【closedir】函数关闭目录,以释放资源。
4.【closedir】
4.1函数原型
【int closedir(DIR *dirp);】
4.2函数功能
关闭目录流指针
4.3函数参数
4.4返回值
5.【readdir】
5.1函数原型
【struct dirent *readdir(DIR *dirp);】
5.2函数功能
从目录流中读取下一个目录项的结构体信息
**说明:**
(1)目录流:目录流是一个抽象的概念,指的是与目录相关联的文件描述符和目录缓存,它可以用于读取目录中的目录项。
(2)目录项:文件系统的目录项(directory entry)是一个数据结构(见5.4返回值),用于建立文件名和文件的【inode】号之间的映射关系。每个目录都是一个文件,它包含了多个目录项,每个目录项包含了一个文件名和一个 inode 号,以及一些其他的元数据信息,如文件类型、权限、所有者、所属组、大小、创建时间、修改时间等。
当用户访问某个文件时,系统会根据文件名查找对应的目录项,获取该文件的【inode】号,然后根据【inode】号读取文件的内容。
(3)目录遍历问题:【readdir】注意一点就是成功时返回目录流【dirp】中下一个目录项,是自动跳到下一个,这样结合【while】就可以遍历整个目录了。
5.3函数参数
5.3.1【dirp】
目录流指针
5.4返回值
5.4.1返回值类型
【成功】:返回包含目录项信息的空间首地址
【失败】:返回NULL
【读到文件末尾】:返回NULL
5.4.2返回值相关说明
5.4.2.1目录项的结构体
原见【man】手册:
【struct dirent {
ino_t d_ino; /* Inode number( 目录的inode) */
off_t d_off; /* Not an offset; see below (目录文件开头至此目录进入点的偏移)*/
unsigned short d_reclen; /* Length of this record(d_name的长度,不包含NULL字符) */
unsigned char d_type; /* Type of file; not supported by all filesystem types(d_type指向的文件类型) */
char d_name[256]; /* Null-terminated filename (目录名)*/
};】
5.4.2.2【d_ino】
5.4.2.3【d_off】
5.4.2.4【d_reclen】
5.4.2.5【d_type】
Linux文件类型:
【DT_REG】:普通文件
【DT_DIR】:目录文件
【DT_FIFO】:命名管道
【DT_SOCK】:套接字文件
【DT_CHR】:字符设备文件
【DT_BLK】:块设备文件
【DT_LNK】:符号链接文件
5.4.2.6【d_name】
5.5源码示例
注意:【pp->d_name】只包含文件名,不包括路径。如果要获取文件的完整路径,可以将文件名和路径拼接起来。另外,当读取完所有的目录项后,【readdir】函数会返回【NULL】,表示目录读取结束。
6【chdir】
6.1函数原型
【int chdir(const char *path);】
6.2函数功能
改变调用进程中当前工作目录为指定路径的目录。
**注意:**
(1)调用进程需要有搜索整个目录的权限。
(2)每个进程都具有一个当前工作目录。在解析相对目录引用时,该目录是搜索路径的起始目录。
(3)如果调用进程更改了目录,则它只对该进程有效,而不能影响调用它的那个进程。
(4)程序结束,返回最初的那个工作目录。
6.3函数参数
6.3.1【path】
指定的路径
6.4返回值
【成功】:返回0
【失败】:返回-1
7.【getcwd】
7.1函数原型
【char *getcwd(char *buf, size_t size);】
7.2函数功能
获取当前工作目录的绝对路径:获取当前进程的工作目录的绝对路径放在大小为size的buf中
7.3函数参数
7.3.1【buf】
存放当前工作目录的缓冲区
7.3.2【size】
缓冲区大小
7.4返回值
【成功】:buf中保存当前进程工作目录
【失败】:NULL
7.5源码示例
8【access】
8.1函数原型
【int access(const char *pathname, int mode);】
8.2函数功能
检测调用函数的程序对文件是否拥有指定权限
8.3函数参数
8.3.1【pathname】
文件路径
8.3.2【mode】
【R_OK】:检测是否拥有读权限
【W_OK】:检测是否拥有写权限
【X_OK】:检测是否拥有执行权限
【F_OK】:检测文件是否存在
8.4返回值
【有该权限】:返回0
【出错】:返回-1
8.5源码示例
9目录的遍历