While recently working on a project, I needed to create a
series of subdirectories from a user supplied string. These could
be two, three, four or more deep. Of course the MSVC Help files
lived up to their normal level of support. After beating my head
aginst the wall I finally realized I could only create a single
subdirectory at one time. In other words if none of the sub-directories
previously existed then the code CreateDirectory("C:\Data\Test\Monday\Backup\Archive")
would continually fail.
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
Set up a CStringArray to hold the Directories in order on
creation.
Parse the passed CString Object into the CString variable
tem one character at a time.
When we get to a \ pass it up and add "tem" to
the CStringArray.
We need to add the \ at the end of the tem variable in
order to continue to separate the directories.
Continue to do this until the entire string is parsed.
**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
Skip the first entry since it is the Drive letter
Cycle through the CStringArray testing to see if the
directory already exists. If it does then go to the next
item.
If the directory does not exist then use
CreateDirectory().
When we reach the end of the CStringArray, check to
see if the full directory actually was created. If it was
then return TRUE, otherwise return FALSE;
Don't forget to clear the array (Good Housekeeping)
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.
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
color="#990000">
WIN32_FIND_DATA fileinfo; // File Information Structure
color="#990000">
CStringArray m_arr; // CString Array to hold Directory Structures
color="#990000">
BOOL tt; // BOOL used to test if Create Directory was successful
color="#990000">int x1 = 0; // Counter
color="#990000">
CString tem = ""; // Temporary CString Object
color="#990000"> 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
color="#990000">if(fileinfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
{
// Directory Exists close file and return
color="#990000">
FindClose(fFile);
return TRUE;
}
m_arr.RemoveAll(); // Not really necessary - Just habit
Separate the String into its compounded componentsfor(x1 = 0; x1 < dd.GetLength(); x1++ ) // Parse the supplied CString Directory String
color="#990000">
{
if(dd.GetAt(x1) != '\\') // if the Charachter is not a \
color="#990000">
tem += dd.GetAt(x1); // add the character to the Temp String
color="#990000">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
color="#990000">
}
if(x1 == dd.GetLength()-1) // If we reached the end of the String
add the remaining string
m_arr.Add(tem);
}
// Close the file
color="#990000">
FindClose(fFile);
Create each level of the Directory Structure// Now lets cycle through the String Array and create each directory in turn
color="#990000">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
color="#990000">if(tt)
SetFileAttributes(tem,FILE_ATTRIBUTE_NORMAL);
// If we were successful we set the attributes to normal
color="#990000">
}
// Now lets see if the directory was successfully created
color="#990000">
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
color="#990000">
FindClose(fFile);
return TRUE;
}
else
{
// For Some reason the Function Failed Return FALSE
color="#990000">
FindClose(fFile);
return FALSE;
}
}
Add www.codeguru.com to your favorites Add www.codeguru.com to your browser search box IE 7 | Firefox 2.0 | Firefox 1.5.xReceive news via our XML/RSS feed
RATE THIS ARTICLE:
Excellent Very Good Average Below Average Poor
(You must be signed in to rank an article. Not a member? Click here to register)