Создание нового каталога на C

96

Я хочу написать программу, которая проверяет наличие каталога; если этот каталог не существует, он создает каталог и файл журнала внутри него, но если каталог уже существует, он просто создает новый файл журнала в этой папке.

Как мне сделать это на C с Linux?

Джигар Патель
источник
1
Функция mkdir создает новый каталог, blog.tremend.ro/2008/10/06/…
fsonmezay
1
возможно, это потому, что вы можете найти решение в Google или даже здесь, сделав простой поиск stackoverflow.com/search?q=C+make+directory . Кстати, я не тот парень, который проголосовал против.
fsonmezay
Пожалуйста , измените свой вопрос , чтобы показать код , который вы имеете до сих пор . Вы должны включить хотя бы схему (но желательно минимальный воспроизводимый пример ) кода, с которым у вас возникли проблемы, тогда мы можем попытаться помочь с конкретной проблемой. Вам также следует прочитать « Как спрашивать» .
Тоби Спейт

Ответы:

146

Посмотрите, 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);
}

Вы можете видеть руководство этих функций с man 2 statи man 2 mkdirкомандами.

Арно Ле Блан
источник
5
Я считаю, что mkdirпод Linux нужен второй параметр modeв дополнение к path.
Paul R
1
@Uku: передача неправильного количества параметров функции является неопределенным поведением, поэтому, хотя в одном случае это может сработать для вас, вам не следует полагаться на него.
Paul R
3
Какова цель проверки того, что каталог не существует перед его созданием? Даже если stat сообщает, что его еще нет, тем временем его мог создать другой процесс.
Brandin
2
@Brandin Думаю, я слепо ответил на вопрос OP :) Вы правы насчет состояния гонки.
Арно Ле Блан
4
Это будет отмечено большинством хороших статических анализаторов как риск
TOCTOU
22

Вы можете использовать mkdir:

$ man 2 мкдир

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

int result = mkdir("/home/me/test.txt", 0777);
Пол Р
источник
Удалит ли это и заменит существующие каталоги?
jjxtra
@jjxtra :: no, он должен завершиться ошибкой, если каталог уже существует, почти так же, как если бы вы пытались выполнить ту же операцию из командной строки.
Paul R
Вот что я догадался. Есть ли проблемы с производительностью из-за пропуска проверки статистики и использования mkdir каждый раз?
jjxtra
@jjxtra: если вы не создаете тысячи каталогов, я не могу себе представить, что будет какая-то измеримая разница в производительности.
Paul R
7

Я хочу написать программу, которая (...) создает каталог и (...) файл внутри него

поскольку это очень распространенный вопрос, вот код для создания нескольких уровней каталогов и последующего вызова 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);
}
Йенс Хармс
источник
3
просто мои 5 копеек - режим 0777 для директории может быть нежелателен - может быть, 0755 лучше, или вообще передать по параметру?
ivan.ukr