Creating a file, when the parent directories might not exist

Started by
10 comments, last by chollida1 19 years, 1 month ago
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.
Advertisement
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:
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 :).

 // 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());
Thanks.

Its a shame there isnt a libary function that will do this for you.
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.
-Mike
BOOL MakeSureDirectoryPathExists(PCSTR DirPath):
http://msdn.microsoft.com/library/en-us/debug/base/makesuredirectorypathexists.asp
Dion Picco - It is simply very, very fast to render nothing.
You can also use

int mkdir(const char*)

found in direct.h
mkdir won't create intermediate directories.
-Mike

This topic is closed to new replies.

Advertisement