Search code examples
c++qtqt4qtcoreqdir

Copying Directory and sub directory


Hi im try to copy a directory and all its contents. I thought a good start is to list all the sub directories so i can get an idea and copy the sub structure to my destination folder.

but i need to get the path from the QDir onwards not the path from the root of the machine, how do i do this so i get sweetassurfwear/folder/folder instaed of /usr/local/websites/sweetassurfwear/folder/folder

here is my code so far

QDir targetDir1("/home/brett/sweetback");
targetDir1.mkdir("sweetassurfwear");

QDir targetDir("/usr/local/websites/sweetassurfwear");
targetDir.setFilter(QDir::NoDotAndDotDot| QDir::Dirs | QDir::Files);
QDirIterator it(targetDir, QDirIterator::Subdirectories);
while (it.hasNext()) {
    QFileInfo Info(it.next().relativePath());
    QString testName = QString(Info.fileName());
    QString testPath = QString(Info.absoluteFilePath());
    if(Info.isDir()){
    //  QString cpd = "/home/brett/sweetback/sweetassurfwear/";
    //  targetDir.mkdir(cpd+testName);
        QString dirname = Info.filePath();
        ui.textEdit->append(QString("Copy Files " + dirname));
    }

}

Solution

  • The problem is that as I wrote in the comment, you are constructing the file info with the full path as opposed to relative path as you wish to have.

    There are two approaches, both presented below, to solve the issue:

    1) The work around would be to remove the "prefix" manually by string manipulation.

    2) The nicer solution would be to get the relative path out of the absolute and root paths by using the corresponding QDir convenience method.

    main.cpp

    #include <QDir>
    #include <QDirIterator>
    #include <QString>
    #include <QFileInfo>
    #include <QDebug>
    int main()
    {    
        QDir targetDir("/usr/local");
        targetDir.setFilter(QDir::NoDotAndDotDot| QDir::Dirs | QDir::Files);
    
        QDirIterator it(targetDir, QDirIterator::Subdirectories);
        while (it.hasNext()) {
            it.next();
            QFileInfo Info = it.fileInfo();
            QString testName = Info.fileName();
    
            // Work around
            // QString testPath = Info.absoluteFilePath().mid(it.path().size()+1);
    
            // Real solution
            QString testPath = QString(targetDir.relativeFilePath(Info.absoluteFilePath()));
    
            qDebug() << "TEST:" << testPath;
            if(Info.isDir()) {
                //  QString cpd = "/home/brett/sweetback/sweetassurfwear/";
                //  targetDir.mkdir(cpd+testName);
                QString dirname = Info.filePath();
            }
        }
    
        return 0;
    }
    

    main.pro

    TEMPLATE = app
    TARGET = main
    QT = core
    SOURCES += main.cpp
    

    Build and run

    qmake && make && ./main
    

    Note that, you do not really need to build a file info based on the path since the QDirIterator instance can return that directly.