Creating a file, when the parent directories might not exist
Suppose I want to creat a file
c:\x\y\z.txt
the directories x and y do not exist. Is there a function i can call in win32 that will create the directories for me if they dont exist? Or will I have to manually parse the file path to obtain the parent directories of the file and create them each.
Parsing strings in C/C++ isnt exactly fun, but none of the create fle functions seem to create the directories for you automatically.
There's no function to do it that I know of, I just ended up writing my own function. I'll look for it now, but I can't remember what damn project it was in...
Gottit:
If you don't like std::string, you'll have to convert it yourself I'm afraid :P
The algorithm is pretty simple. Just keep searching for the next \ or / character, and create that directory. It'll try to create C:, and that'll fail, but that doesn't matter, it'll continue and create C:\x then C:\x\y then it'll do an fopen("C:\x\y\z.txt","wb").
FILE* CreateFileAndPath(const string& strPathAndFile){string strPath(strPathAndFile);string strCurrent;int nStart, nStart1, nStart2; // Create the path // while(strPath.length()) { nStart1 = (int)strPath.find('/'); if(nStart1 == string::npos) nStart1 = INT_MAX; nStart2 = (int)strPath.find('\\'); if(nStart2 == string::npos) nStart2 = INT_MAX; nStart = min(nStart1,nStart2); if(nStart == INT_MAX) break; strCurrent += strPath.substr(0,nStart)+"\\"; strPath.erase(strPath.begin(),strPath.begin()+nStart+1); CreateDirectory(strCurrent.c_str(),NULL); } // Create the file // return fopen(strPathAndFile.c_str(),"wb");}
If you don't like std::string, you'll have to convert it yourself I'm afraid :P
The algorithm is pretty simple. Just keep searching for the next \ or / character, and create that directory. It'll try to create C:, and that'll fail, but that doesn't matter, it'll continue and create C:\x then C:\x\y then it'll do an fopen("C:\x\y\z.txt","wb").
another thing you can do...
did this from my head so there may be errors :).
did this from my head so there may be errors :).
// split the path into its components char drive[MAX_PATH]; char dir[MAX_PATH]; char fname[MAX_PATH]; char ext[MAX_PATH]; _splitpath(filename, drive, dir, fname, ext); // SHCreateDirectoryEx creates all intermediate directories string path = string(drive) + string(dir); SHCreateDirectoryEx(0, path.c_str(), 0); // create file string fullpath = path + string(fname) + string(ext); ofstream file(fullpath.c_str());
You could let the boost library do most of the work for you:
// create a file, plus any required directoriesstd::ofstream CreateFileAndRequiredDirectories(const std::string& filePath){ // just to simplify things... namespace filesystem = boost::filesystem; using boost::filesystem::path; // create a boost path object representing the file path; path filePathObject(filePath, filesystem::native); if(!filesystem::exists(filePathObject.branch())) { // if the file's parent directory doesn't exist, // then we need to do a little more work... // create a path object to represent the file's parent directory path dirPath(filePathObject.branch(), filesystem::native); // ...walk through each directory in the parent directory path // from root to absolute path and create any parent directories // that don't exist yet path partialPath("", filesystem::native); path::iterator currPath = dirPath.begin(); path::iterator endPath = dirPath.end(); while(currPath != endPath) { partialPath /= path(*currPath, filesystem::native); if(!filesystem::exists(partialPath)) { filesystem::create_directory(partialPath); } ++currPath; } } return std::ofstream(filePath);}
Quote:Its a shame there isnt a libary function that will do this for you
Dead Eye told you a library function that will do it - SHCreateDirectory.
BOOL MakeSureDirectoryPathExists(PCSTR DirPath):
http://msdn.microsoft.com/library/en-us/debug/base/makesuredirectorypathexists.asp
http://msdn.microsoft.com/library/en-us/debug/base/makesuredirectorypathexists.asp
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement