Sunday, August 2, 2009

C++: How to create an MFC application that will rename files in a directory?

As a part of a larger MFC application written in C++ (Visual Studio 2005), I would like to include a function that will read in all the filenames in a given directory and rename them to append the date that the file was created to the end of the filename.





Thus, files that were previously named, "hello.txt" and were created on 1/1/2007 would now be named, "hello010107.txt".





Is there an easy way to do this? Keep in mind, this is an MFC application (with windows, buttons, forms, etc), not a console application.

C++: How to create an MFC application that will rename files in a directory?
Here ya go:





#include %26lt;afxtempl.h%26gt;





void TimeStampFiles(CString Path)


{


// enumerate all files in the directory and place them in an array


CStringArray files;


CFileFind finder;


BOOL bWorking = finder.FindFile(Path + "\\*.*");


while (bWorking)


{


// ignore directories


bWorking = finder.FindNextFile();


if (!finder.IsDirectory())


files.Add(finder.GetFilePath());


}





// now cycle through the array


for (int i=0; i%26lt;files.GetSize(); i++)


{


// get the file path, title and extension


CString path = GetPath(files[i]); // e.g. "c:\\dir\\"


CString title = GetTitle(files[i]); // e.g. "name"


CString extension = GetExtension(files[i]); // e.g. "ext"





// get the time for this file


CTime time;


finder.GetCreationTime(time);





// construct the string


CString timeString = time.Format("%m%d%Y");





// construct the new filename


CString newName = path + title + timeString + "." + extension;





// rename it


CFile::Rename(files[i], newName);


}


}





What this does is first enumerate all the files and place them in an array....you don't want to be modifying the contents of a directory while you're looping through it. It then goes through the array and names each file at a time. The only functions I haven't implemented are the 3 that seperate the full path and filename into the path, the file title and the extension, but they should be easy enough to look up.





Enjoy!
Reply:You can do it, but there is no 'easy way' shortcut.





You need to use FindFirstFile() and FindNextFile() to iterate through the files in the directory. Here's sample code: http://netez.com/2xExplorer/shellFAQ/bas...





Be sure to explicitly ignore '.' and '..' when iterating through the file names and also ignore subdirectories. See sample code for how to determine whether you're looking at a filename or a subdir name.





Collect all the valid file names into a container (vector would work). Once you are done getting all the file names, start iterating through your vector. Parse the existing file name at the dot, and build your new file name, then call ::MoveFileEx( ) to rename the file. Be sure you use the full path in the file names.





How are you planning to use this? You'll only be able to run it once on a directory. If you run it a second time, you'll keep expanding the already-renamed files with more date decoration. Maybe you need a more unique naming convention so you can decide that the file is already renamed and leave it alone.


No comments:

Post a Comment