大家好,我是情报小哥~
在进行Linux C语言程序开发的时候,你肯定遇到过这样一个问题:为什么标准 mkdir 函数无法创建多级目录?
因为标准 POSIX mkdir 函数被设计为单级目录创建工具,所以无法直接创建多级目录。然而,这样的设计肯定不是Linux做不到,而是有着深思熟虑的系统设计考量。
多级目录创建需要多次文件系统操作,每个中间目录都需要权限验证 如果 mkdir 自动创建多级目录,会绕过应用程序对权限的精细控制,可能无意中在用户无权访问的位置创建目录,违反“除非明确要求,否则不做额外工作”的 UNIX 哲学。
在创建多级路径时,可能在不同层级遇到不同错误(权限、已存在、空间不足),需要保持操作的原子性(要么全成功,要么全失败),系统调用应保持简单,错误处理复杂任务应交给应用程序。
mkdir 系统调用最早出现在 AT&T UNIX System III (1980年),当时的文件系统结构简单(通常只有1-2层目录),多级目录需求在文件系统复杂化后才出现,保持老代码兼容性比增加功能更重要。
2、解决方案对比
肯定有非常多的朋友在开发中需要多级创建目录的,下面是常见的处理方法:
mkdir("/tmp/myapp") | ||||
mkdir_p() | ||||
system("mkdir -p a/b/c") |
我个人还是比较喜欢自己封装一个C语言函数来进行处理,调用系统命令总感觉怪怪的,下面是我的代码供参考使用:
#include <sys/stat.h>#include <sys/types.h>#include <string.h>#include <errno.h>#include <stdio.h>#include <limits.h>/** * mkdir_p - 递归创建多级目录(类似于 mkdir -p) * @param path 目录路径 * @param mode 权限(如 0755) * @return 0 成功,-1 失败(errno 设置) */int mkdir_p(const char *path, mode_t mode) { char tmp[PATH_MAX]; size_t len; char *p, *end;if (!path || !*path) { errno = EINVAL;return-1; } len = strlen(path);if (len >= sizeof(tmp)) { // 防止溢出 errno = ENAMETOOLONG;return-1; } strncpy(tmp, path, sizeof(tmp)); tmp[sizeof(tmp) - 1] = '\0';// 去掉末尾连续斜杠,但保留根目录"/" end = tmp + len - 1;while (end > tmp && *end == '/') *end-- = '\0';// 处理根目录if (strcmp(tmp, "/") == 0) return0;for (p = tmp + 1; *p; p++) {if (*p == '/') { *p = '\0';// 跳过重复斜杠和"."、".."if (strlen(tmp) > 0 && strcmp(tmp, ".") != 0 && strcmp(tmp, "..") != 0) {if (mkdir(tmp, mode) != 0 && errno != EEXIST) {return-1; } } *p = '/';// 跳过连续斜杠while (*(p + 1) == '/') p++; } }// 最后一级目录if (strlen(tmp) > 0 && strcmp(tmp, ".") != 0 && strcmp(tmp, "..") != 0) {if (mkdir(tmp, mode) != 0 && errno != EEXIST) {return-1; } }return0;}
END
作者:Mr.Deng