Создать рекурсивный файл в C Linux - PullRequest
0 голосов
/ 02 августа 2020

Я хочу создать файл test по этому пути /tmp/a1/a2/a3/a4/test

Но все каталоги (a1..a4) не существуют. Как я могу создать этот файл в C at Linux ОС?

Ответы [ 3 ]

2 голосов
/ 02 августа 2020

Ниже приведена полная функция в C, которая выполняет то, что вы хотите.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

int create_file_with_parent_dirs (char pathname[])
{
    for (char *p = pathname; (p = strchr(p ,'/')) != NULL; ++p) {
        char c = p[1];
        p[1] = '\0';
        errno = 0;
        if (mkdir(pathname, 0700) != 0 && errno != EEXIST) {
            perror("mkdir");
            return -1;
        }
        p[1] = c;
    }
    int fd = creat(pathname, 0600);
    if (fd < 0)
        perror("creat");
    return fd;
}

int main (void)
{
    char pathname[] = "/tmp/a1/a2/a3/a4/test";
    create_file_with_parent_dirs(pathname);
}

Обратите внимание, что массив, на который указывает pathname, должен быть изменяемым. Не вызывайте функцию со строковым литералом. Также имейте в виду, что файл будет обрезан до нулевой длины, если он уже существует.

2 голосов
/ 02 августа 2020

Вы можете использовать функцию mkdir из sys/stat.h для создания каталогов по мере необходимости. Например,

mkdir("/tmp/a1",0766);

Однако вы должны проверить с помощью stat, существуют ли уже каталоги.

После того, как вы создали структуру каталогов, ваш файл может быть создан с

open("/tmp/a1/a2/a3/a4/test",O_WRONLY|O_CREAT);

Очевидно, вам необходимо проверить возвращаемые значения всех этих вызовов функций.

0 голосов
/ 02 августа 2020

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

 #include <dirent.h>
 #include <errno.h>
 #include <bits/stdc++.h>
 #include <iostream>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <vector>
 #include <fstream>
 using namespace std;
 int checkDir(char * path)
 {
    DIR* dir = opendir(path);
    if (dir) {
            
            /* Directory exists. */
            closedir(dir);
            return 0;
    } else if (ENOENT == errno) {
            /* Directory does not exist. */
            return -1;
    } else {
            /* opendir() failed for some other reason. */
            return -2;
    }
 }
 int make_dir(char *path)
 {
    int ret = checkDir(path);
    if( ret == -1)
         {
                 if (mkdir(path, 0777) == -1)
            {
                         cerr << "Error :  " << strerror(errno) << endl;
                    return -1;
            }
 
                 else
            {
                         cout << "Directory created";
                    return 0;
            } 
         }
    return ret;
 
 }
 int main(int args, char **argv)
 {
    std::string strpath(argv[1]);
    std::string delimeter = "/";
    std::string substr1 = "";
    int cnt = 0;
    std::vector<string> strPaths;
    std::string strbck = strpath;

            for( int i = strpath.find(delimeter);  i != std::string::npos; i = strpath.find(delimeter))
    {
            if(cnt > 0)
            {
                    substr1 = strbck.substr(0,  substr1.length() + i + 1);
                    strPaths.push_back(substr1);
            }

            strpath = strpath.substr(i +1,strpath.length());
            cnt++;
    }
    strPaths.push_back(strbck);
    std::string str;

    for_each( strPaths.begin() ,strPaths.end() -1 , [](std::string str) {make_dir((char*)str.c_str());});
    ofstream outfile;
    std::ofstream file {strPaths[strPaths.size() -1].c_str() };
    file << "hello"<< std::endl;
    file.close();
                    return 0;
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...