Copying a Directory

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Tyler
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 246
Joined: Fri Sep 03, 2004 12:37 am
Contact:

Copying a Directory

Postby Tyler » Thu Apr 28, 2005 11:01 pm

Per our previous discussion over at: http://forums.wxwidgets.org/viewtopic.php?t=1833 I finally got around to laying down the copy dir function. I think it's pretty handy. Thanks for the input on it. I incorporated the ideas from the thread. Please edit it if you think it's bloated, and if it's not usefull to anyone then my appologies for the following graffiti:

Code: Select all

// =================================================================
//   Date:      04/28/05
//   Author:      ... doesn't matter ...
//   Platforms:   Written and tested under Win XP
//  Compiler:   MSVC++ 6.0
//   wxWidgets:   Tested under 2.6.0, but should work in others.
//
//   Description:  Copies one directory contents to another,
//      creating the destination directory if it does not exist.  I'm sure
//      there might be better ways to do this, but this should work.
//
//  Resources:  Original discussion at:
//      http://wxforum.shadonet.com/viewtopic.php?t=1833
//
//  Example Usage: 
//
//      CopyDir("C:\\dev\\test", "c:\\devCopy\\testCopy");
// =================================================================
bool CopyDir(wxString from, wxString to) {

   // set up our proper directory slash character.  If running on
   // windows, __WXMSW__ should be defined in the preprocessor definitions!
   // this is just how i handle slashes. anyone know a more efficient way?
   #ifdef __WXMSW__
      wxString SLASH = "\\";
   #else
      wxString SLASH = "/";
   #endif

   // append a slash if there is not one (for easier parsing)
   // because who knows what people will pass to the function.
   if (to[to.length()-1] != SLASH) {
      to += SLASH;   
   }
   // for both dirs
   if (from[from.length()-1] != SLASH) {
      from += SLASH;   
   }

   // first make sure that the source dir exists
   if(!wxDir::Exists(from)) {
      wxLogError(from + " does not exist.  Can not copy directory.");
   }
   else {
      // check on the destination dir
      // if it doesn't exist...
      if(!wxDir::Exists(to)) {
         // if it doesn't get created
         if(!wxFileName::Mkdir(to, 0777, wxPATH_MKDIR_FULL)) {
            // Send an error
            wxLogError(to + " could not be created.");
            // And exit gracefully
            return false;
         }
      }

      // The directories to traverse
      wxArrayString myDirs;
      // Initially we want one pass
      myDirs.Add("");
      
      // loop through each directory.. storing all sub directories
      // and copying over all files.. the final iteration of one loop
      // should begin an iteration for any subdirectories discovered
      // on the previous pass
      // (rather than pragma, unsigned int will shut the MS compiler up)
      for (unsigned int i = 0; i < myDirs.size(); i++) {

         // get the next directory
         wxDir nextDir(from + myDirs[i]);

         // check that it exists in destination form
         if(!wxDir::Exists(to + myDirs[i])) {
            // if it doesn't, then create it
            if(!wxFileName::Mkdir(to + myDirs[i], 0777, wxPATH_MKDIR_FULL)) {
               // If it doesn't create, error
               wxLogError(to + myDirs[i] + " could not be created.");
               // And exit gracefully
               return false;
            }
         }

         // get the first file in the next directory
         wxString nextFile;
         bool process = nextDir.GetFirst(&nextFile);

         // and while there are still files to process
         while (process) {

            // If this file is a directory
            if(wxDir::Exists(from+nextFile)) {
               // then append it for creation/copying
               myDirs.Add(nextFile + SLASH);   // only add the difference
            }
            else {

               // otherwise just go ahead and copy the file over
               if(!wxCopyFile(from + myDirs[i] + nextFile,
                           to   + myDirs[i] + nextFile)) {
                  // error if we couldn't
                  wxLogError("Could not copy " +
                     from + myDirs[i] + nextFile + " to "
                     + to + myDirs[i] + nextFile);
               }
            }
            // and get the next file
            process = nextDir.GetNext(&nextFile);
         }

      }
   
      return true;
   }

   return false;
}
// =================================================================
Last edited by Tyler on Fri Apr 29, 2005 3:31 pm, edited 1 time in total.

Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Postby Jorg » Fri Apr 29, 2005 7:05 am

Very nice. But for your information, you don't have to define the slash character to be appended. You can use wxFileName and call AppendDir to append a directory name, where the slash is taken care for on the proper OS :-)

But it is a very useful piece of code indeed..

Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb

Tyler
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 246
Joined: Fri Sep 03, 2004 12:37 am
Contact:

Postby Tyler » Fri Apr 29, 2005 3:23 pm

Hey Jorg,

Thanks. I will edit it some time to use wxFileName::AppendDir. I don't like relying on preprocessor definititions necessarily.

-Tyler

RyanAlt
In need of some credit
In need of some credit
Posts: 6
Joined: Tue May 03, 2005 8:49 am

Re: Copying a Directory

Postby RyanAlt » Tue May 17, 2005 4:47 pm

Tyler wrote: // set up our proper directory slash character. If running on
// windows, __WXMSW__ should be defined in the preprocessor definitions!
// this is just how i handle slashes. anyone know a more efficient way?
#ifdef __WXMSW__
wxString SLASH = "";
#else
wxString SLASH = "/";
#endif


wxFILE_SEP_PATH
I got voted off the wxIsland!

goeba
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue May 17, 2005 8:13 pm

Postby goeba » Tue May 17, 2005 8:17 pm

Hi,

I

Avi
Super wx Problem Solver
Super wx Problem Solver
Posts: 398
Joined: Mon Aug 30, 2004 9:27 pm
Location: Tel-Aviv, Israel

Postby Avi » Tue May 17, 2005 8:37 pm

Instead of using a do-while loop for recursion... you might want the function to call itself every time it reaches a subfolder... ;)

goeba
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue May 17, 2005 8:13 pm

Postby goeba » Wed May 18, 2005 5:38 am

That

Tyler
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 246
Joined: Fri Sep 03, 2004 12:37 am
Contact:

Postby Tyler » Wed May 18, 2005 5:58 pm

RyanAlt wrote:wxFILE_SEP_PATH


Ok, now that is cool. :!: I always have a hard time digging up these details, so thanks for providing that. That's a much more elegant solution.

[quote="goeba"]Hi,

I

Avi
Super wx Problem Solver
Super wx Problem Solver
Posts: 398
Joined: Mon Aug 30, 2004 9:27 pm
Location: Tel-Aviv, Israel

Postby Avi » Wed May 18, 2005 6:43 pm

[quote="goeba"]That

MoonKid
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 543
Joined: Wed Apr 05, 2006 9:39 am
Contact:

link to source?

Postby MoonKid » Fri Apr 07, 2006 9:04 pm

Is there a link to the source files? Can I use it? What is about the licencs?

Why is it not in the official wxWidgets?

Mr.shi
Earned a small fee
Earned a small fee
Posts: 13
Joined: Fri Jul 13, 2007 3:05 am

Postby Mr.shi » Sun Jul 15, 2007 3:16 am

if ( ! wxEndsWithPathSeparator( to ) )
{
to += wxFILE_SEP_PATH;
}

if ( ! wxEndsWithPathSeparator( from ) )
{
from += wxFILE_SEP_PATH;
}

Dark Alchemist
Super wx Problem Solver
Super wx Problem Solver
Posts: 347
Joined: Wed Nov 02, 2005 10:33 am

Postby Dark Alchemist » Thu Oct 02, 2008 10:45 pm

Did this function ever get incorporated into WxWidgets?

The only typo I saw was (due to the forum removing one back slash)

Code: Select all

    #ifdef __WXMSW__
            wxString SLASH = "\\";
    #else
            wxString SLASH = "/";
    #endif
it should read

Code: Select all

    #ifdef __WXMSW__
            wxString SLASH = "\\\";
    #else
            wxString SLASH = "/";
    #endif
but beyond that it works and would be wonderful if added into WxWidgets (if it hasn't been already).

SandyHip
Earned a small fee
Earned a small fee
Posts: 11
Joined: Wed Jun 02, 2010 9:44 am

Re: Copying a Directory

Postby SandyHip » Thu Dec 15, 2011 2:43 pm

I have solved to write recursive function copying catalogue

Code: Select all

bool wxCopyDir(wxString sFrom, wxString sTo)
{
    if (sFrom[sFrom.Len() - 1] != '\\' && sFrom[sFrom.Len() - 1] != '/') sFrom += wxFILE_SEP_PATH;
    if (sTo[sTo.Len() - 1] != '\\' && sTo[sTo.Len() - 1] != '/') sTo += wxFILE_SEP_PATH;

    if (!::wxDirExists(sFrom)) {
        ::wxLogError(wxT("%s does not exist!\r\nCan not copy directory"), sFrom.c_str());
        return false;
    }
    if (!wxDirExists(sTo)) {
        if (!wxFileName::Mkdir(sTo, 0777, wxPATH_MKDIR_FULL)) {
            ::wxLogError(wxT("%s could not be created!"), sTo.c_str());
            return false;
        }
    }

    wxDir fDir(sFrom);
    wxString sNext = wxEmptyString;
    bool bIsFile = fDir.GetFirst(&sNext);
    while (bIsFile) {
        const wxString sFileFrom = sFrom + sNext;
        const wxString sFileTo = sTo + sNext;
        if (::wxDirExists(sFileFrom)) {
            wxCopyDir(sFileFrom, sFileTo);
        }
        else {
            if (!::wxFileExists(sFileTo)) {
                if (!::wxCopyFile(sFileFrom, sFileTo)) {
                    ::wxLogError(wxT("Could not copy %s to %s !"), sFileFrom.c_str(), sFileTo.c_str());
                    return false;
                }
            }
        }
        bIsFile = fDir.GetNext(&sNext);
    }
    return true;
}

wx0Pal
In need of some credit
In need of some credit
Posts: 1
Joined: Wed Feb 01, 2012 8:07 pm
Contact:

Re: Copying a Directory

Postby wx0Pal » Wed Feb 01, 2012 11:10 pm

Hello,

I wonder why newly created directories have to have "0777" access rights ? Isn't it potentially dangerous, from the security point of view ? Not to mention that it wouldn't work if the target directory has more restricted access right requirements than the process that tries to copy it.

I would propose to copy access control list from the target directory rather than forcing it to be fully accessible.

By the way, +1 for recursive approach proposal.

Regards

User avatar
Nucleorion
Knows some wx things
Knows some wx things
Posts: 45
Joined: Sat Jan 07, 2017 10:08 pm

Re: Copying a Directory

Postby Nucleorion » Sat Feb 11, 2017 7:32 pm

What libraries are needed?


Return to “The Code Dump”

Who is online

Users browsing this forum: No registered users and 1 guest