Are there any function in C or C++ or WinApi to create directory including all unexistent directories in specified path?

StackOverflow https://stackoverflow.com/questions/19188087

質問

I need an analog of c#

Directory.CreateDirectory("d:\\asd\\dsa\\123");

which will create all that directories, even if disk D is totally empty with no any directories.

I read about WinApi CreateDirectory next thing:
"ERROR_PATH_NOT_FOUND - One or more intermediate directories do not exist; this function will only create the final directory in the path."
So it's not what I looking for..

Any other ways to do what I want?

役に立ちましたか?

解決

Did you try to use mkdir() function ? Another way to use:

  1. boost filesystem: supports standard MAX_PATH size 260.

    const char dir_path[] = "c:\\temp\\cplusplus";

    boost::filesystem::path dir(dir_path);
            if(boost::filesystem::create_directory(dir)) {
                std::cout << "Success" << "\n";
            }
    
  2. SHCreateDirectoryEx function for Win XP(SP2) and Higher. However, it is limited to 247 characters, which is less than the standard MAX_PATH (260) that other Win32 API filesystem functions support

  3. CreateDirectory function : default string size limit for paths of 248 characters. This limit is related to how the CreateDirectory function parses paths. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" prefix to the path.

NOTE: Because most Boost.Filesystem operational functions just pass the contents of a class path object to the Windows API, they do work with the extended-length prefixes. But some won't work, because to the limitations imposed by Windows. -- Boost warning.

他のヒント

Check if your particular compiler vendor provides its own RTL function for that purpose. For example, Delphi/C++Builder has a ForceDirectories() function available.

Well, in Perl/Ruby/Bash you would,

    `/bin/mkdir -p $pathname` #perl
    %x(/bin/mkdir -p #{pathname}) #ruby
    /bin/mkdir -p $pathname #bash

So you could evoke system,

    system("mkdir -p pathname");

Added:

Well, you want to split the given path into parts and make each part. Easy enough to do in C (change char* and char[] to std::string, strcat to += for c++),

int MakeDir( char* pathname )
{
    struct stat sbuf;
    if( stat(pathname, &sbuf) < 0 )
    {
        mkdir(pathname,0); //set your permissions as you like in 2nd argument
        return(0);
    }
    else //exists? skip
    {
        //stat.st_mode tells file or dir
        if( S_ISDIR(stat.st_mode) ) { return(0); }
        else if( S_ISREG(stat.st_mode) ) { return(-1); }
        else if( S_ISFIFO(stat.st_mode) ) { return(-1); }
        else if( S_LNK(stat.st_mode) ) { return(0); } //can link to dir
        else { return(-1); }
    }
    return(0);
};
////char PATHSEP = "\/"; //unix/linux //not needed, just use 'mkdir -p'
char PATHSEP = "\\"; //windows
int MkdirPath( char *pathname )
{
    char parts = strdup(pathname);
    char buildpath[strlen(pathname)] = "";
    char* part = strtok(parts,PATHSEP);
    while ( part )
    {
        strcat(pathname, PATHSEP); strcat(pathname, part);
        if( MakeDir( pathname ) < 0 ) { break; }
        part = strtok(NULL,PATHSEP);
    }
    return(0);
};
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top