Linux目录操作学习总结
一、核心概念
-
目录的本质
- Linux中目录是一种特殊文件,存储当前目录下的文件及子目录信息。
- 根目录为
/
,所有文件和目录均从根目录开始组织。
-
目录操作核心函数
- 打开目录:
DIR *opendir(const char *name)
- 读取目录项:
struct dirent *readdir(DIR *dir)
- 关闭目录:
int closedir(DIR *dir)
- 创建目录:
int mkdir(const char *pathname, mode_t mode)
- 删除空目录:
int rmdir(const char *dirname)
- 重命名/删除文件:
int rename(const char *oldpath, const char *newpath)
、int remove(const char *pathname)
- 打开目录:
二、关键数据结构
1. DIR
结构体
typedef struct __dirstream DIR; // 表示目录流,用于操作目录
- 通过
opendir
返回的DIR*
指针管理目录流。
2. dirent
结构体
struct dirent {
ino_t d_ino; // 索引节点号
off_t d_off; // 目录文件中的偏移
unsigned short d_reclen; // 记录长度
unsigned char d_type; // 文件类型标识
char d_name[256]; // 文件名(最长255字符)
};
d_type
取值:enum { DT_UNKNOWN = 0, // 未知类型 DT_FIFO = 1, // 管道文件 DT_CHR = 2, // 字符设备文件 DT_DIR = 4, // 目录 DT_BLK = 6, // 块设备文件 DT_REG = 8, // 普通文件 DT_LNK = 10, // 符号链接 DT_SOCK = 12 // 套接字文件 };
三、目录操作函数详解
1. 遍历目录并输出文件信息
#include <dirent.h>
#include <stdio.h>
int main() {
DIR *dir = opendir("."); // 打开当前目录
if (!dir) {
perror("目录打开失败");
return 1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) { // 逐项读取目录内容
printf("文件名: %-20s 类型: ", entry->d_name);
switch (entry->d_type) {
case DT_REG: printf("普通文件\n"); break;
case DT_DIR: printf("目录\n"); break;
case DT_LNK: printf("符号链接\n"); break;
default: printf("其他类型\n");
}
}
closedir(dir); // 关闭目录
return 0;
}
输出示例:
文件名: . 类型: 目录
文件名: .. 类型: 目录
文件名: test.txt 类型: 普通文件
文件名: link 类型: 符号链接
2. 创建目录并检查权限
#include <sys/stat.h>
#include <stdio.h>
int main() {
if (mkdir("new_dir", 0755) == -1) { // 创建目录,权限为rwxr-xr-x
perror("目录创建失败");
return 1;
}
printf("目录创建成功\n");
return 0;
}
输出:
目录创建成功
四、综合例题
题目:实现类似ls -l
的功能,输出目录下文件的详细信息(名称、类型、inode号)。
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
int main() {
DIR *dir = opendir(".");
if (!dir) {
perror("目录打开失败");
return 1;
}
struct dirent *entry;
struct stat st;
while ((entry = readdir(dir)) != NULL) {
if (stat(entry->d_name, &st) == -1) {
perror("stat失败");
continue;
}
printf("文件名: %-15s Inode: %-8lu 类型: ", entry->d_name, st.st_ino);
switch (entry->d_type) {
case DT_REG: printf("普通文件\n"); break;
case DT_DIR: printf("目录\n"); break;
case DT_LNK: printf("符号链接\n"); break;
default: printf("其他类型\n");
}
}
closedir(dir);
return 0;
}
输出示例:
文件名: . Inode: 123456 类型: 目录
文件名: test.txt Inode: 789012 类型: 普通文件
文件名: link Inode: 345678 类型: 符号链接
五、常见问题
- 目录遍历遗漏:
readdir
不会自动过滤.
(当前目录)和..
(上级目录),需手动处理。 - 文件类型判断:
d_type
可能返回DT_UNKNOWN
(如某些文件系统不支持),此时需用stat
函数进一步检查。 - 权限不足:创建目录时需确保父目录有写权限。
总结
- 核心操作:打开、遍历、关闭目录是目录操作的基础,需熟练使用
opendir
、readdir
、closedir
。 - 数据结构:
dirent
结构体提供文件名和类型,结合stat
可获取更详细属性(如inode、大小)。 - 应用场景:
- 文件管理器开发
- 批量文件处理(如备份、清理)
- 系统工具实现(如
ls
、find
)
通过结合目录操作函数和文件属性查询,可实现复杂的文件系统管理功能。