Cで新しいディレクトリを作成する


96

ディレクトリの存在をチェックするプログラムを書きたいです。そのディレクトリが存在しない場合は、ディレクトリとその中にログファイルが作成されますが、ディレクトリがすでに存在する場合は、そのフォルダに新しいログファイルが作成されます。

LinuxのCでこれを行うにはどうすればよいですか?


1
mkdir関数は新しいディレクトリblog.tremend.ro/2008/10/06/…を
fsonmezay

1
多分それは、単純な検索stackoverflow.com/search?q=C+make+directoryを作成することで、Googleまたはここでも解決策を見つけることができるためです。ちなみに私は反対票を投じた男ではありません。
fsonmezay 2011

質問を編集し、現在のコードを表示しください。問題が発生しているコードの概要(できれば最小限の再現可能な例)を含める必要があります。そうすれば、特定の問題の解決に努めることができます。How to Askもお読みください
Toby Speight

回答:


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
mkdirLinuxではmode、に加えて2つ目のパラメータが必要だと思いますpath
ポールR

1
@Uku:誤った数のパラメーターを関数に渡すことは未定義の振る舞いなので、1つのインスタンスで機能するように見えるかもしれませんが、それに依存するべきではありません。
ポールR

3
作成する前にディレクトリが存在しないことを確認する目的は何ですか?それがまだ存在しないとstatが言っても、その間に別のプロセスがそれを作成した可能性があります。
ブランディン

2
@ブランディン私は盲目的にOPの質問に答えたと思います:)あなたはレース状態について正しいです。
Arnaud Le Blanc

4
これは、ほとんどの優れた静的アナライザーによってTOCTOUリスクとしてフラグが付けられます
kdopen

22

mkdirを使用できます。

$ man 2 mkdir

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

int result = mkdir("/home/me/test.txt", 0777);

既存のディレクトリを削除して置き換えますか?
jjxtra 2017年

@jjxtra ::いいえ、コマンドラインから同じ操作を試みた場合と同じように、ディレクトリがすでに存在する場合は失敗します。
ポールR

それは私が推測したものです。統計チェックをスキップして毎回mkdirを実行するだけでパフォーマンスの問題はありますか?
jjxtra 2017年

@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セント-dirのモード0777は望ましくないかもしれません-おそらく0755の方が良いですか、それともパラメーターで渡すのですか?
ivan.ukr 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.