CreatePath - Full Path Creation (wstring version)
This is a simple function I wrote in order to deal with creating complete (multi-level) paths.
The function works recursively, and uses std::wstring, but can actaully work on any basic_string -based string. It can deal with trailing slashes (eg. "c:\temp\" vs. "c:\temp"), as well as network locations (eg. "\\machine\shared").
You might notice the call to SetLastError(). The reason is to make it easy to verify what went wrong in case of an error - instead of handling exceptions and/or error strings, all you have to do is call GetLastError() if the function returns false.
You can use the function to make sure a directory exists before creating a file in it:
std::wstring wsFileName;
int pos = wsFileName.find_last_of(L"\\");
if (0 <= pos)
{
std::wstring wsPath = wsFileName.substr(0, pos);
if (CreatePath(wsPath))
{
CreateFileW(wsFileName.c_str(), ...);
}
else
{
std::wcout << L"Error #" << GetLastError() << std::endl;
}
}
Here is the source code:
bool CreatePath(std::wstring &wsPath)
{
DWORD attr;
int pos;
bool result = true;
// Check for trailing slash:
pos = wsPath.find_last_of(SLASH);
if (wsPath.length() == pos + 1) // last character is "\"
{
wsPath.resize(pos);
}
// Look for existing object:
attr = GetFileAttributesW(wsPath.c_str());
if (0xFFFFFFFF == attr) // doesn't exist yet - create it!
{
pos = wsPath.find_last_of(SLASH);
if (0 < pos)
{
// Create parent dirs:
result = CreatePath(wsPath.substr(0, pos));
}
// Create node:
result = result && CreateDirectoryW(wsPath.c_str(), NULL);
}
else if (FILE_ATTRIBUTE_DIRECTORY != attr)
{ // object already exists, but is not a dir
SetLastError(ERROR_FILE_EXISTS);
result = false;
}
return result;
}

Comments
yFxhAE gp Og Efp lrYb Pr
Posted by YCtBTCuwiU on 01/27/2013 03:51ambuy generic viagra buy cheap viagra online us - viagra stories
ReplyThis is my piece of code for the same prupose. You forgot an important thing.
Posted by Legacy on 02/13/2004 12:00amOriginally posted by: My code
I think my code is better and more efficient.
Don't forget to consider other language.
The '\\' caracter may be part of multibyte character in other language like Chinese.
Use CharNextExA instead.
void LoopCreateDirectory(LPSTR dpath)
{
LPSTR pname;
for( LPSTR pdir=pname=dpath; *pdir; pdir=CharNextExA(CP_ACP,pdir,0))
if(*pdir=='\\')
{
*pdir=0;
CreateDirectory(pname,NULL);
*pdir='\\';
}
}
Reply
Problem with GetFileAttributes and similar functions
Posted by Legacy on 10/25/2002 12:00amOriginally posted by: Madbawa
These functions have a problem when the supplied path contains a double slash ('\\') somewhere in the middle. I deliberately put the \\ to test invalid paths, but sadly it doesn't give an INVALID_HANDLE or NULL pointer.
ReplySimilar but cheaper and faster iterative solution
Posted by Legacy on 06/10/2002 12:00amOriginally posted by: Arbesto Pelta
ReplyFunny no one mentioned it so far...
Posted by Legacy on 06/09/2002 12:00amOriginally posted by: Assaf Tzur-El
... but you might create yourself a small bug if you try to use the wsPath parameter after the function returns. The function takes its string parameter by reference, but it's NOT const, so the path might be changed inside the function. If you rely on the path staying the same, you might have a bug (your own bug, by the way, not mine - you should always check const-ness :) )
The fix is simple - remove the reference char, and make the function look like this:
bool CreatePath(std::wstring wsPath)
Please note that if the function should be thread-safe and you are using Microsoft's STL, you should explicitly copy the string before passing it to the function. The reason is MS's obscene handling of reference counter for strings, which is NOT thread-safe. Feel free to email me for more information about this.
Share and Enjoy,
ReplyAssaf.
Use MakeSureDirectoryPathExists
Posted by Legacy on 01/16/2002 12:00amOriginally posted by: Andrew
Why not?
BOOL MakeSureDirectoryPathExists(PCSTR DirPath);
See MSDN Platform SDK
Reply
Why BOOL and GetLastError?
Posted by Legacy on 01/16/2002 12:00amOriginally posted by: NortonNealson
Nice function, but I have a more general question.
What makes you return a BOOL and then when FALSE require the caller to call GetLastError instead of just returning an error number or zero for success?
I have nothing against using Get/SetLastError but feel it should be used when the return value cannot be used to indicate success and an error number. For example a function that returns a pointer or a handle where a NULL is often used to indicate failure.
This may just be a coding style and is my opinion. I'm interested in hearing what you and others think about this.
ReplyThanks,