C++ Verzeichnisse kopieren

Hey Leute,

bin durch google auf euer Forum und auch auf einen Thread mit einer ähnlichen Problematik gestoßen und hoffe das mir jemand helfen kann. Der Thread konnte es leider nicht :/

Im Prinzip sollte mein Code alle Ordner, Unterordner und Dateien vom angegebenen Quellpfad aus zum Zielpfad kopieren, gegebenenfalls müssen Ordner neu erstellt werden. Soweit zur Theorie.
Mein Programm läuft auch schon, aber eben nur teilweise bzw es tut nicht das was ich erwarte.

Momentan geht es ins Quellverzeichnis und geht wenn es einen Ordner findet diesen durch. Danach beendet es sich. Das ist aber leider nur die halbe Miete.

Dateien kopieren, Ordner erstellen funktioniert ohne Probleme, das einzige was es nicht tut ist wirklich alle Unterordner und Dateien zu behandeln.

Hier nun noch mein Quellcode.
Code:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
void CopyDir(string sSource, string sDest);

void CopyDir(string sSource, string sDest)
{
     WIN32_FIND_DATA FData;
     string tempSource;
     string tempDest;
     string sSourcePath;

     tempSource = sSource;
     tempSource += "\\*";

     HANDLE hFile = FindFirstFile(tempSource.c_str(), &FData);
     if ( hFile == INVALID_HANDLE_VALUE )
     {
         cerr << "error while opening input folder: " << 
tempSource.c_str() << endl;
         throw new exception("Hier muss was sinnvolles rein");
     }


     do
     {
         //ignore directories ".", ".." and ".s(vn)"
         if (!( ( FData.cFileName[0] == '.') && ( ( FData.cFileName[1] 
== '.' && FData.cFileName[2] == 0) || FData.cFileName[1] == 0 || 
FData.cFileName[1] == 's') ) )
         {
             if( FData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) // 
Directories finden und wegschreiben, rekursiver Selbstaufruf
             {
                 //build new destination path
                 sDest += "\\";
                 sDest += FData.cFileName;
                 //create directory, if it already exists the function fails
                 CreateDirectory(sDest.c_str(), NULL);

                 cout <<"Dest: " << sDest.c_str() << endl;

                 //build new source path
                 sSource += "\\";
                 sSource+= FData.cFileName;

                 cout <<"Source: " << sSource.c_str() << endl;
                 //rekursiver Selbstaufruf
                 CopyDir(sSource, sDest);
             }
             else // Dateien finden und wegschreiben
             {
                 //zielpfad zusammenbasteln
                 tempDest = sDest;
                 tempDest += "\\";
                 tempDest += FData.cFileName;

                 cout <<"Dest: " << tempDest.c_str() << endl;
                 //quellpfad zusammenbasteln
                 sSourcePath = sSource ;
                 sSourcePath += "\\";
                 sSourcePath += FData.cFileName;

                 cout <<"Source: " << sSourcePath.c_str() << endl;

                 //copy files, if they already exist the function fails
                 CopyFile(sSourcePath.c_str(), tempDest.c_str(), TRUE);
             }

         }

     }while (FindNextFile( hFile, &FData) == TRUE );
     FindClose(hFile);
}


int _tmain(int iArgc, _TCHAR** ppArgv)
{
     if ( iArgc < 3 || iArgc > 3 )
     {
         cerr << "Usage: Program <src> <dst>" << endl;
         return 1;
     }

     try
     {
         CreateDirectory(ppArgv[2], NULL);
         CopyDir(ppArgv[1], ppArgv[2]);
         return 1;
        //Nun sind alle Files ins Ziel kopiert, sollten sie noch nicht 
vorhanden gewesen sein
     }
     catch ( exception &e )
     {
         cerr << e.what() << endl;
         return 1;
     }
     catch ( ... )
     {
         cerr << "unknown error" << endl;
         return 1;
     }

     return 0;
}

Ich hoffe ihr könnt mir helfen den Fehler zu finden^^

Edit: Ich weiß jetzt nicht obs relevant ist, das ganze programmiere ich mit VS2010 in C++.


Gruß und Danke schonmal im vorraus.
 
Zuletzt bearbeitet:
Ich seh jetzt so direkt keinen Fehler, würde ihn am ehesten aber bei }while (FindNextFile( hFile, &FData)); vermuten. Probiers mal mit einem explizitem TRUE, also } while(FindNextFile(hFile, &FData) == TRUE);.
 
Guten morgen,

erstmal danke für den Tip.
Hab es grad mal umgesetzt, leider ändert sich dadurch nix :/

Hat vielleicht noch jemand anders eine Idee wo das Problem liegen könnte?


Gruß
 
Zuletzt bearbeitet:
Hallöle,

hab das ganze jetzt etwas anders gelöst, ob es soo elegant ist, weiß ich zwar nicht, aber es läuft.

Hier mal meine Lösung falls es jemanden intressiert.

Code:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;
void CopyDir(vector<string> &vsDirSource, vector<string> &vsDirDest);
void CopyFiles(string sSource, string sDest, WIN32_FIND_DATA FData);

//find and write all directories
void CopyDir(vector<string> &vsDirSource, vector<string> &vsDirDest)
{
    WIN32_FIND_DATA FData;
    string tempSource;
    string tempDest;
    string sSourcePath;
    string akSource;
    string akDest;

    sSourcePath = vsDirSource[0];
    sSourcePath += "\\*";
    tempSource = vsDirSource[0];
    tempDest = vsDirDest[0];

    HANDLE hFile = FindFirstFile(sSourcePath.c_str(), &FData);
    if ( hFile == INVALID_HANDLE_VALUE )
    {
        cerr << "error while opening input folder: " << sSourcePath.c_str() << endl;
        throw new exception("Hier muss was sinnvolles rein");
    }

    do
    {
        //ignore directories ".", ".." and ".svn"
        if (!( ( FData.cFileName[0] == '.') && ( ( FData.cFileName[1] == '.' && FData.cFileName[2] == 0) || FData.cFileName[1] == 0 || 
            ( FData.cFileName[1] == 's' && FData.cFileName[2] == 'v' && FData.cFileName[3] == 'n' ) ) ) )
        {
            if( FData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) // find and write directories
            {
                akSource = vsDirSource[0];
                akSource += "\\";
                akSource += FData.cFileName;

                akDest = vsDirDest[0];
                akDest += "\\";
                akDest += FData.cFileName;

                //create directory, if it already exists the function fails
                CreateDirectory(akDest.c_str(), NULL);

                //write paths in vector
                vsDirDest.push_back(akDest.c_str());
                vsDirSource.push_back(akSource.c_str());
            }
        
        }
    
    }while (FindNextFile( hFile, &FData) == TRUE);
    CopyFiles(tempSource, tempDest, FData);
    //erase first element of the vector
    vsDirSource.erase(vsDirSource.begin());
    vsDirDest.erase(vsDirDest.begin());
    //if the vector is empty leave function, else recursive call
    if ( vsDirSource.empty() && vsDirDest.empty() )
        FindClose(hFile);
    else
        CopyDir(vsDirSource, vsDirDest);
}

//find and write all files
void CopyFiles(string sSource, string sDest, WIN32_FIND_DATA FData)
{
    string tempDest;
    string tempSource;
    string Source;
    Source = sSource;
    Source += "\\*";

    HANDLE hFile = FindFirstFile(Source.c_str(), &FData);
    do
    {
        if(! (FData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) 
        {
            //build destination path
            tempDest = sDest;
            tempDest += "\\";
            tempDest += FData.cFileName;

            cout <<"Dest: " << tempDest.c_str() << endl;
            //build source path
            tempSource = sSource ;
            tempSource += "\\";
            tempSource += FData.cFileName;

            cout <<"Source: " << tempSource.c_str() << endl;

            //copy files, if they already exist the function fails
            CopyFile(tempSource.c_str(), tempDest.c_str(), TRUE);
        }
    }while (FindNextFile( hFile, &FData) == TRUE);
    FindClose(hFile);
}

int _tmain(int iArgc, _TCHAR** ppArgv)
{
    if ( iArgc < 3 || iArgc > 3 )
    {
        cerr << "Usage: Program <src> <dst>" << endl;
        return 1;
    }

    try
    {
        vector<string> vsDirSourcePathList;
        vector<string> vsDirDestPathList;
        vsDirSourcePathList.push_back(ppArgv[1]);
        vsDirDestPathList.push_back(ppArgv[2]);
        CreateDirectory(ppArgv[2], NULL);
        CopyDir(vsDirSourcePathList, vsDirDestPathList);
        return 1;
       //Nun sind alle Files ins Ziel kopiert, sollten sie noch nicht vorhanden gewesen sein
    }
    catch ( exception &e )
    {
        cerr << e.what() << endl;
        return 1;
    }
    catch ( ... )
    {
        cerr << "unknown error" << endl;
        return 1;
    }

    return 0; 
}

Auf jedenfall vielen Dank für die Hilfe :)

Gruß
 
Zurück
Oben