目录检索
1. 基本概念
Linux 目录检索指在 Linux 操作系统中使用目录检索工具来查找文件和目录的过程。
Linux 的文件系统包括一个根目录(/),这个目录包含了 Linux 系统中所有的文件和目录。在根目录下,还有许多子目录,每个子目录都有自己的用途,如 “/etc” 目录用于存放系统配置文件,“/usr” 目录用于存放用户程序,“/var” 目录用于存放可变文件等。
要查找文件和目录,可以使用 Linux 中的目录检索工 具,如“ls”命令。使用“ls”命令时,可以指定要查找的目录,也可以使用通配符来匹配文件名,例如 “ls /etc/*.conf” 表示查找 “/etc” 目录下所有以 “.conf” 为扩展名的文件。
除了“ls”命令,还有许多其他的目录检索工具,如 “find” 命令可以在指定的目录中查找满足特定条件的文件,“grep” 命令可以用于搜索文本文件中的关键字。总之,Linux 提供了丰富的目录检索工具,可以帮助用户快速查找到所需的文件和目录。Linux 库函数中也给我们提供了一些目录操作的 API。
2. 目录操作API
2.1 目录项结构体
在 Linux 系统中的目录项结构体:
struct dirent
{
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all filesystem types */
char d_name[256]; /* filename */
};
typedef struct
{
int dd_fd; /* file descriptor */
int dd_loc; /* offset in current buffer */
int dd_size; /* amount of data returned by getdents */
char *dd_buf; /* data buffer */
struct dirent *dd_next; /* next entry to read */
} DIR;
2.2 打开目录操作
opendir()
函数用于打开一个目录,并返回目录流,用于读取目录中的文件。函数原型为:
DIR *opendir(const char *name);
该函数接受一个参数:
name
:指定要打开的目录的路径。该函数返回一个指向
DIR
结构体的指针,该结构体包含有关目录的信息。如果打开目录失败,则返回NULL
。
2.3 关闭目录操作
closedir()
函数用于关闭一个打开的目录流。函数原型为:
int closedir(DIR *dirp);
该函数接受一个参数:
dirp
:指向打开的目录流的指针,由opendir()
函数返回。该函数返回 0 表示成功,返回非 0 值表示失败。
2.4 创建目录操作
mkdir()
函数用于在指定的路径下 创建一个新目录。函数原型为:
int mkdir(const char *pathname, mode_t mode);
该函数接受两个参数:
pathname
:指定要创建新目录的路径。mode
:指定新目录的权限。该函数返回 0 表示成功,返回非 0 值表示失败。
2.5 目录项偏移操作
seekdir()
函数用于更改目录流的当前位置。函数原型为:
void seekdir(DIR *dirp, long loc);
该函数接受两个参数:
dirp
:指向打开的目录流的指针,由opendir()
函数返回。loc
:指定新的当前位置。该函数没有返回值。
2.6 读取目录操作
readdir()
函数用于读取目录流中的下一个条目。函数原型为:
struct dirent *readdir(DIR *dirp);
该函数接受一个参数:
dirp
:指向打开的目录流的指针,由opendir()
函数返回。该函数返回一个指向
dirent
结构体的指针,该结构体包含有关目录条目的信息。如果已到达目录流的末尾,则返回NULL
。
2.7 目录删除操作
remove()
函数用于删除指定路径下的文件或目录。函数原型为:
int remove(const char *pathname);
该函数接受一个参数:
pathname
:指定要删除的文件或目录的路径。该函数返回 0 表示成功,返回非 0 值表示失败。注意,该函数只能删除空目录。如果要删除非空目录,可以使用
rmdir()
函数。
注意:这个函数也可以用来删除文件。
3. 路径操作API
3.1 改变当前工作目录
chdir()
函数用于更改当前工作目录。函数原型为:
int chdir(const char *path);
该函数接受一个参数:
path
:指定要更改为的新工作目录的路径。该函数返回 0 表示成功,返回非 0 值表示失败。
3.2 获取当前绝对路径
getcwd()
函数用于获取当前工作目录。函数原型为:
char *getcwd(char *buf, size_t size);
该函数接受两个参数:
buf
:指向字符数组的指针,该字符数组用于保存当前工作目录的路径。size
:指定buf
数组的大小,以便确定buf
数组的最大长度。该函数返回值为指向字符数组
buf
的指针,表示当前工作目录的路径。如果发生错误,则返回 NULL。
4. 示例代码
4.1 简单示例
演示打开目录、读取目录并打印wen'j、关闭目录。
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main(int argc, char *argv[])
{
// 打开目录
DIR *dp = opendir(".");
if (dp == NULL) {
perror("opendir() fail");
exit(1);
}
// 读取目录文件
struct dirent *d;
while ((d = readdir(dp)) != NULL) {
// 打印目录文件名
printf("%s\n", d->d_name);
}
// 关闭目录
closedir(dp);
return 0;
}
4.2 简单示例
演示创建目录、切换路径、删除目录。
下面是一个示例代码,它使用这些函数来在当前目录中创建一个名为 "temp" 的子目录,然后将当前工作目录更改为该子目录,并在其中创建一个名为 "test.txt" 的文件,然后将当前工作目录更改回原来的目录,并删除 "temp" 子目录。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
// 创建 "temp" 子目录
int ret = mkdir("temp", 0644);
if (ret != 0) {
perror("mkdir() fail");
exit(1);
}
// 更改当前工作目录为 "temp" 子目录
ret = chdir("temp");
if (ret != 0){
perror("chdir() fail");
exit(1);
}
// 在 "temp" 子目录中创建 "test.txt" 文件
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) {
perror("fopen() fail");
exit(1);
}
// 关闭 "test.txt" 文件
fclose(fp);
// 打印当前目录
char buf[256] = {0};
getcwd(buf, 256);
printf("当前目录:%s\n", buf);
// 将当前工作目录更改回原来的目录
if (chdir("..") == -1) {
perror("chdir() fail");
exit(1);
}
// 打印当前目录
getcwd(buf, 256);
printf("当前目录:%s\n", buf);
// 删除 "temp" 子目录
if (rmdir("temp") == -1) {
perror("rmdir() fail");
exit(1);
}
return 0;
}
因为 rmdir
只能删除一个非空的目录,所以上面的删除目录操作肯定是失败的。