使用Qt复制目录

Sij*_*ith 20 qt qt4 directory-traversal

我想将目录从一个驱动器复制到另一个驱动器.我选择的目录包含许多子目录和文件.

如何使用Qt实现相同的功能?

pet*_*tch 18

void copyPath(QString src, QString dst)
{
    QDir dir(src);
    if (! dir.exists())
        return;

    foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
        QString dst_path = dst + QDir::separator() + d;
        dir.mkpath(dst_path);
        copyPath(src+ QDir::separator() + d, dst_path);
    }

    foreach (QString f, dir.entryList(QDir::Files)) {
        QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f);
    }
}
Run Code Online (Sandbox Code Playgroud)


mos*_*osg 12

手动,你可以做下一件事:

1).使用下面的func生成文件夹/文件列表(递归) - 目标文件.

static void recurseAddDir(QDir d, QStringList & list) {

    QStringList qsl = d.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);

    foreach (QString file, qsl) {

        QFileInfo finfo(QString("%1/%2").arg(d.path()).arg(file));

        if (finfo.isSymLink())
            return;

        if (finfo.isDir()) {

            QString dirname = finfo.fileName();
            QDir sd(finfo.filePath());

            recurseAddDir(sd, list);

        } else
            list << QDir::toNativeSeparators(finfo.filePath());
    }
}
Run Code Online (Sandbox Code Playgroud)

2).然后你可以开始将文件从目标列表复制到新的源目录,如下所示:

for (int i = 0; i < gtdStringList.count(); i++) {

    progressDialog.setValue(i);
    progressDialog.setLabelText(tr("%1 Coping file number %2 of %3 ")
        .arg((conf->isConsole) ? tr("Making copy of the Alta-GTD\n") : "")
        .arg(i + 1)
        .arg(gtdStringList.count()));

    qApp->processEvents(QEventLoop::ExcludeUserInputEvents);

    if (progressDialog.wasCanceled()) {

        // removing tmp files/folders
        rmDirectoryRecursive(tmpFolder);
        rmDirectoryRecursive(tmpFolderPlus);
        setEnableGUI(true);
        return;
    }

    // coping
    if (!QFile::copy(gtdStringList.at(i), tmpStringList.at(i))) {

        if (warningFlag) {

            QMessageBox box(this);
            QString name = tr("Question");
            QString file1 = getShortName(gtdStringList.at(i), QString("\\...\\"));
            QString file2 = getShortName(tmpStringList.at(i), QString("\\...\\"));
            QString text = tr("Cannot copy <b>%1</b> <p>to <b>%2</b>"   \
               "<p>This file will be ignored, just press <b>Yes</b> button" \
               "<p>Press <b>YesToAll</b> button to ignore other warnings automatically..."  \
               "<p>Or press <b>Abort</b> to cancel operation").arg(file1).arg(file2);

            box.setModal(true);
            box.setWindowTitle(name);
            box.setText(QString::fromLatin1("%1").arg(text));
            box.setIcon(QMessageBox::Question);
            box.setStandardButtons(QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::Abort);

            switch (box.exec()) {                   
                case (QMessageBox::YesToAll):
                    warningFlag = false;
                    break;
                case (QMessageBox::Yes):
                    break;
                case (QMessageBox::Abort):
                    rmDirectoryRecursive(tmpFolder);
                    rmDirectoryRecursive(tmpFolderPlus);
                    setEnableGUI(true);
                    return;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

就这样.祝好运!

  • 让我们说这是`d.path()`中保存的内容,`file`中有`text.txt`.'%1'将被`d.path()`替换为`c:\ cyg\ftp%3a%2f%2fcygwin.mirrorcatalogs.com%2fcygwin%2f /%2`.最后你将拥有`c:\ cyg\ftp%3atext.txtftext.txtfcygwin.mirrorcatalogs.comtext.txtfcygwintext.txtf/text.txt`.更好的选择是`d.path().append('/').append(file)` (3认同)
  • 我试过将我的更正作为编辑发布,但似乎没有人理解它,所以我将其发布在这里。使用 `QString("%1/%2").arg(d.path()).arg(file)` 通常不是一个好主意,因为可以找到 '%1' 或 '%2'(在大多数文件系统)在文件名或路径名中。以cygwin创建的这个路径为例`c:\cyg\ftp%3a%2f%2fcygwin.mirrorcatalogs.com%2fcygwin%2f`。 (2认同)

roo*_*oop 7

我想要类似的东西,并且谷歌搜索(徒劳),所以这是我必须的:

static bool cpDir(const QString &srcPath, const QString &dstPath)
{
    rmDir(dstPath);
    QDir parentDstDir(QFileInfo(dstPath).path());
    if (!parentDstDir.mkdir(QFileInfo(dstPath).fileName()))
        return false;

    QDir srcDir(srcPath);
    foreach(const QFileInfo &info, srcDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
        QString srcItemPath = srcPath + "/" + info.fileName();
        QString dstItemPath = dstPath + "/" + info.fileName();
        if (info.isDir()) {
            if (!cpDir(srcItemPath, dstItemPath)) {
                return false;
            }
        } else if (info.isFile()) {
            if (!QFile::copy(srcItemPath, dstItemPath)) {
                return false;
            }
        } else {
            qDebug() << "Unhandled item" << info.filePath() << "in cpDir";
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

它使用rmDir看起来非常相似的功能:

static bool rmDir(const QString &dirPath)
{
    QDir dir(dirPath);
    if (!dir.exists())
        return true;
    foreach(const QFileInfo &info, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
        if (info.isDir()) {
            if (!rmDir(info.filePath()))
                return false;
        } else {
            if (!dir.remove(info.fileName()))
                return false;
        }
    }
    QDir parentDir(QFileInfo(dirPath).path());
    return parentDir.rmdir(QFileInfo(dirPath).fileName());
}
Run Code Online (Sandbox Code Playgroud)

这不处理链接和特殊文件,顺便说一句.


sho*_*osh 6

艰难的方式.单独复制每个文件.

  • 使用QDir::entryList()遍历目录的内容
  • 使用QDir::cd()QDir::cdUp()进出目录
  • 使用QDir::mkdir()QDir::mkpath()创建新的文件夹树
  • 最后,用于QFile::copy()复制实际文件