Create Multiple Level Subdirectories
I finally realized that the function CreateDirectory is only a wrapper for _mkdir which will only create a single sub-directory so I would need to recursively call CreateDirectory() several times. Since there is really no way around this I created a small subroutine WriteDir() which takes care of all of the work for me.
What are the steps required
**Note** Notice we have to add the final value of tem to the CString Array since there is NO \ at the end of the Directory String
Now we can start creating the directories
From the Example: Original CString = C:\Data\Test\Monday\Backup\Archive
CStringArray members [0] = C: [1] = C:\Data [2] = C:\Data\Test [3] = C:\Data\Test\Monday [4] = C:\Data\Test\Monday\Backup [5] = C:\Data\Test\Monday\Backup\Archive Remeber we skipped the first entry. Then we cycled through and created each string independently.
How do we put this to use
Add the files WriteDir.h and WriteDir.cpp to your project. Add #include "WriteDir.h" in the cpp file where you are going to call the function. Set up a test variable: BOOL test; CString someString; Set someString to a Directory path you need to create (Do not add a \ at the end of the string) test = WriteDir(someString);
if test == TRUE SUCCESS if test == FALSE FAILURE
The Source Code
#include "stdafx.h" #include "WriteDir.h"
Setup Internal Variables
BOOL WriteDirectory(CString dd)
{
HANDLE fFile; // File Handle
WIN32_FIND_DATA fileinfo; // File Information Structure
CStringArray m_arr; // CString Array to hold Directory Structures
BOOL tt; // BOOL used to test if Create Directory was successful
int x1 = 0; // Counter
CString tem = ""; // Temporary CString Object
Before we go to a lot of work. Check to see if the Directory exists
fFile = FindFirstFile(dd,&fileinfo);
// if the file exists and it is a directory
if(fileinfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
// Directory Exists close file and return
FindClose(fFile);
return TRUE;
}
m_arr.RemoveAll(); // Not really necessary - Just habit
Separate the String into its compounded components
for(x1 = 0; x1 < dd.GetLength(); x1++ ) // Parse the supplied CString Directory String
{
if(dd.GetAt(x1) != '\\') // if the Charachter is not a \
tem += dd.GetAt(x1); // add the character to the Temp String
else
{
m_arr.Add(tem); // if the Character is a \
Add the Temp String to the CString Array
tem += "\\"; // Now add the \ to the temp string
}
if(x1 == dd.GetLength()-1) // If we reached the end of the String
add the remaining string
m_arr.Add(tem);
}
// Close the file
FindClose(fFile);
Create each level of the Directory Structure
// Now lets cycle through the String Array and create each directory in turn
for(x1 = 1; x1 < m_arr.GetSize(); x1++)
{
tem = m_arr.GetAt(x1);
tt = CreateDirectory(tem,NULL);
// If the Directory exists it will return a false
if(tt)
SetFileAttributes(tem,FILE_ATTRIBUTE_NORMAL);
// If we were successful we set the attributes to normal
}
// Now lets see if the directory was successfully created
fFile = FindFirstFile(dd,&fileinfo);
Check to see if the Directory was created and it actually is a Directory
m_arr.RemoveAll();
if(fileinfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
// Directory Exists close file and return
FindClose(fFile);
return TRUE;
}
else
{
// For Some reason the Function Failed Return FALSE FindClose(fFile); return FALSE; } }

Comments
WriteDirectory() fails sporadically, fix found.
Posted by Chr on 08/14/2012 08:10amWriteDirectory() sporadically failed. My computer is running windows 7/32. I could fix the problem by checking the result of FindFirstFile(). This does not make sense, because FindClose() should also work with invalid handles, however this fix works: fFile = FindFirstFile(cs_directory_to_create,&fileinfo;); if (INVALID_HANDLE_VALUE != fFile) { ...
ReplyBug Fix
Posted by rossini on 07/06/2004 03:02pmCreate folder by current date
Posted by Legacy on 01/22/2004 12:00amOriginally posted by: san dinfer
can any one help me how to create a folder
Replyplease help me in creating folders
Posted by Legacy on 01/19/2004 12:00amOriginally posted by: afsheen nasir
I want to create folder with vc++ code anybody can help me???
-
ReplyA Lame Attempt !..
Posted by prasadptc on 10/13/2004 08:54amSHCreateDirectory API
Posted by Legacy on 12/17/2003 12:00amOriginally posted by: Josh Hogle
If your code is for Windows 2000 or later, check out the SHCreateDirectory API call.
ReplyPermissions under "Inetpub/wwwroot/" NEED HELP
Posted by Legacy on 08/16/2002 12:00amOriginally posted by: BOBA KOPOBbEB
ReplySimple version without any classes, recursion and uneccessary memory allocations
Posted by Legacy on 07/10/2002 12:00amOriginally posted by: Eugen
BOOL CreateDirectoryTree(LPCTSTR pszDirectory)
{
char szDir[MAX_PATH];
char *p, *pNext;
strcpy (szDir, pszDirectory);
pNext = strchr(szDir, '\\');
if (pNext)
{
pNext++;
while ((p=strchr(pNext, '\\')) != 0)
{
*p = 0;
if (GetFileAttributes (szDir) == -1)
{
if (CreateDirectory(szDir, 0) == FALSE)
{
return FALSE;
}
}
*p = '\\';
pNext = p+1;
}
}
if (GetFileAttributes (szDir) == -1)
{
if (CreateDirectory(szDir, 0) == FALSE)
{
return FALSE;
}
}
return TRUE;
}
-
Reply
ReplyPotential buffer overflow!
Posted by inbugable on 09/28/2004 06:59amTry SHPathPrepareForWrite()
Posted by Legacy on 06/12/2002 12:00amOriginally posted by: Patrick Walsh
You will get a kick out of this one.
It will even prompt the user to format the drive if not formated, mount the network drive etc...
Reply
Problems using recursive logic
Posted by Legacy on 11/15/2001 12:00amOriginally posted by: Ashes
Although recursive logic might be simpler to code, recursive functions use up a lot more stack space. So, the non-recursive original code might be more useful, especially if I am creating very deeply nested paths (4K or greater).
However, I agree using the ImageHlp API is probably the best.
ReplyWOW !!
Posted by Legacy on 06/08/2001 12:00amOriginally posted by: Vikas
See 'MakeSureDirectoryPathExists()'
This's really cool !!
ReplyExcellent method to create multiple level of SubDirectories !!
Loading, Please Wait ...