Sign in to follow this  
CrimsonGT

c++ Recursive renaming of files/directories

Recommended Posts

I am looking for a way in c++ to specify a directory, and then have it search through it, and all sub directories and rename the directories/files it finds. I found rename() in stdio.h but not sure how to search through each sub directory and file to rename them. Any help or code snippets would be appreciated :)

Share this post


Link to post
Share on other sites
My implementation is win32 dependent and uses custom stuff (list , text processing)

Here are the main classes that you can use in order to manipulate files and directories , path , etc.


//--------------------------------------------------------------------------
enum PathObjectFlags
{
is_directory = 1<<0,
is_file = 1<<1,

is_loaded = 1<<2,// if the object is dir , and all the subfolders and files are loaded
};
//--------------------------------------------------------------------------
class Path;
class PathObject
: public ListNode<PathObject>
{
public:
//----------------------------
PathObject();
PathObject(char* Name, unsigned int Flags);
PathObject(PathObject& other);
void operator =(PathObject& other);
~PathObject();
//----------------------------
char* getName()const;
int isFile()const;
void trimExt();
bool hasCildren()const;
unsigned int getFlags()const;
//----------------------------
bool find(Path &out,const char *Name,unsigned int withFlags = is_file);
bool depthFind(Path &out,const char *Name,unsigned int withFlags = is_file);
public:
char* name;
unsigned int flags;
List<PathObject> subs;
private:
bool __find(Path & out , char *name,unsigned int Flags);// breadfirst
private:
friend class Path;
};

//--------------------------------------------------------------------------
class Path
{
public:
Path();
Path(const char* name);
Path(Path& other);
void operator =(Path& other);
//-------------------------------------------------------------------
char* getPath() const;
char* trim();// trim the last object from the path
void operator +=(const char* path);
bool isEmpty()const;
void clear();
//-------------------------------------------------------------------
void ls(List<PathObject>& output, bool files = true, bool dirs = true);
void scan(PathObject& rezult, bool files = true, bool dirs = true);
void mkdir(char* name, bool recursive = false);
hddStream mkfile(const char* name, const char* mode = "wb");
private:
char location[MAX_PATH_LENGTH];
unsigned int length;
};
//--------------------------------------------------------------------------




Basic usage:
Path p("directory") or Path p("c:\\home");
Path p(0); - curent path of the file starting with the drive.. eg: c:\blab la\...
PathObject o; represents a file , or a folder;
p.scan(o); - will search trough all the structure starting from path P;
o- now holds the structure of folders and files; with it you can search inside for stuff, get exact location , etc;

Ps: send a PM if you want the rest of the code , there is to much to post it here.

The base code that can get all the files and folders from a folder is:
Node: only one folder , this will not search inside other folders

WIN32_FIND_DATA fdata;
HANDLE dhandle;
{
char buf[MAX_PATH_LENGTH];

text::append(buf, "\\*", text::append(buf, location));

if ((dhandle = FindFirstFile(buf, &fdata)) == INVALID_HANDLE_VALUE)
{
return;// error
}
}

while (true)
{
if (FindNextFile(dhandle, &fdata))
{
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{//directory
if (dirs && !text::equal("..", fdata.cFileName))
output.add(new PathObject(fdata.cFileName,is_directory));
}
else
{// file
if (files)
output.add(new PathObject(fdata.cFileName,is_file));
}
}
else
{
if (GetLastError() != ERROR_NO_MORE_FILES)
{
break;
}
else
{
FindClose(dhandle);
return;// some sort of an error
}
}/**/
}
//if(FindClose(dhandle) == 0) //error
FindClose(dhandle);



Share this post


Link to post
Share on other sites
Boost version:
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

void recurse(const fs::path & p) {
fs::directory_iterator di(p);
fs::directory_iterator de;

while (di != de) {
try {
if (fs::is_directory(di->status())) {
recurse(di->path());
// fs::rename(di->path(), ....);
}
if (fs::is_regular_file(di->status())) {
// fs::rename(di->path(), ....);
}
} catch (const std::exception & e) {
std::cout << e.what() << std::endl;
}
++di;
}
}

int main()
{
recurse("r:/root");
}

Actual renaming and matching left as exercise.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this