在C中创建一个新目录

Jee*_*tel 85 c linux directory

我想编写一个检查目录是否存在的程序; 如果该目录不存在,那么它会在其中创建目录和日志文件,但如果该目录已经存在,那么它只是在该文件夹中创建一个新的日志文件.

我将如何在C中使用Linux执行此操作?

Arn*_*anc 134

查看stat是否存在目录,

并且mkdir,创建一个目录.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct stat st = {0};

if (stat("/some/directory", &st) == -1) {
    mkdir("/some/directory", 0700);
}
Run Code Online (Sandbox Code Playgroud)

您可以使用man 2 statman 2 mkdir命令查看这些函数的手册.

  • 我相信Linux下的`mkdir`除了`path`之外还需要第二个参数`mode`. (5认同)
  • 在创建目录之前检查目录不存在的目的是什么?即使 stat 说它还不存在,另一个进程也可能在此期间创建了它。 (5认同)
  • 这将被大多数优秀的静态分析仪标记为TOCTOU风险 (4认同)
  • @Uku:将不正确数量的参数传递给函数是未定义的行为,因此虽然它可能在一个实例中对您有用,但您不应该依赖它。 (2认同)
  • @Brandin我想我一味地回答OP的问题:)你对比赛状况是正确的. (2认同)

Pau*_*l R 20

你可以使用mkdir:

$ man 2 mkdir

#include <sys/stat.h>
#include <sys/types.h>

int result = mkdir("/home/me/test.txt", 0777);
Run Code Online (Sandbox Code Playgroud)

  • 直接尝试“mkdir()”而不是先执行“stat()”会更快,因为如果创建了目录,它可以节省一次系统调用。如果目录已经退出,那么成功的 `stat()` 仍然会比不成功的 `mkdir()` 慢,因为 `stat()` 必须做更多的工作才能完成。 (7认同)

Shi*_*ero 9

mkdir要在 C中创建新目录,可以使用<sys/stat.h>. 该函数需要两个参数:新目录的路径及其权限。

int mkdir (const char *filename, mode_t mode)

这是一个例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>

if (mkdir("/some/directory", S_IRWXU | S_IRWXG | S_IRWXO) == -1) {
    printf("Error: %s\n", strerror(errno));
}
Run Code Online (Sandbox Code Playgroud)

关键点:

  1. 权限:mode中的参数指定mkdir目录的权限。为了获得最佳实践,建议使用整数别名modeS_IRWXUS_IRWXGS_IRWXO分别代表用户、组和其他人的读、写和执行权限。在此示例中,S_IROTH | S_IXOTH使用 代替S_IRWXOfor other,这允许其他人读取和执行但不能写入。

  2. 错误检查:如果mkdir返回-1,则发生错误。使用strerror(errno)会给你一个人类可读的错误消息。常见错误包括目录已存在(检查EEXISTin errno

  3. 文档参考:想要更深入的了解权限位,可以参考GNU C Library文档:GNU Permission Bits


小智 5

我想编写一个程序(...)创建目录并在其中创建一个(...)文件

因为这是一个非常常见的问题,所以这里的代码可以创建多个级别的目录,而不是调用fopen。我正在使用gnu扩展名以printf打印错误消息。

void rek_mkdir(char *path) {
    char *sep = strrchr(path, '/');
    if(sep != NULL) {
        *sep = 0;
        rek_mkdir(path);
        *sep = '/';
    }
    if(mkdir(path, 0777) && errno != EEXIST)
        printf("error while trying to create '%s'\n%m\n", path); 
}

FILE *fopen_mkdir(char *path, char *mode) {
    char *sep = strrchr(path, '/');
    if(sep) { 
        char *path0 = strdup(path);
        path0[ sep - path ] = 0;
        rek_mkdir(path0);
        free(path0);
    }
    return fopen(path,mode);
}
Run Code Online (Sandbox Code Playgroud)

  • 只是我的5美分-可能不需要目录0777模式-也许0755更好,甚至通过参数传递? (2认同)
  • @ivan.ukr 0777 是正确的,该模式将由用户 umask 修改。例如。对于 umask 022,结果为 755;对于 umask 007,结果为 770。 (2认同)