web-dev-qa-db-ja.com

Qtを使用してディレクトリをコピーする

あるドライブから別のドライブにディレクトリをコピーしたい。選択したディレクトリには、多くのサブディレクトリとファイルが含まれています。

Qtを使用して同じものを実装するにはどうすればよいですか?

21
Sijith
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);
    }
}
20
petch

手動で、次のことを行うことができます。

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());
    }
}

2)。次に、宛先からファイルのコピーを開始できますlist次のように新しいソースディレクトリにコピーします。

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;
            }
        }
    }
}

そしてそれがすべてです。幸運を!

12
mosg

私は似たようなものが欲しかったのですが、グーグルで(無駄に)いたので、これが私がしなければならないところです:

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;
}

これは、非常によく似た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());
}

ところで、これはリンクや特別なファイルを処理しません。

7
roop

難しい方法。すべてのファイルを個別にコピーします。

  • QDir::entryList()を使用して、ディレクトリのコンテンツを反復処理します
  • QDir::cd()およびQDir::cdUp()を使用して、ディレクトリに出入りします
  • QDir::mkdir()およびQDir::mkpath()を使用して、新しいフォルダツリーを作成します
  • 最後に、QFile::copy()を使用して実際のファイルをコピーします
6
shoosh

これを試して:

bool copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
    QDir sourceDir(fromDir);
    QDir targetDir(toDir);
    if(!targetDir.exists()){    /* if directory don't exists, build it */
        if(!targetDir.mkdir(targetDir.absolutePath()))
            return false;
    }

    QFileInfoList fileInfoList = sourceDir.entryInfoList();
    foreach(QFileInfo fileInfo, fileInfoList){
        if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
            continue;

        if(fileInfo.isDir()){    /* if it is directory, copy recursively*/
            if(!copyDirectoryFiles(fileInfo.filePath(),  
                targetDir.filePath(fileInfo.fileName()), 
                coverFileIfExist)) 
                return false;
        }
        else{            /* if coverFileIfExist == true, remove old file first */
            if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
                targetDir.remove(fileInfo.fileName());
            }

            // files copy
            if(!QFile::copy(fileInfo.filePath(),  
                targetDir.filePath(fileInfo.fileName()))){ 
                    return false;
            }
        }
    }
    return true;
}
2
ljc123456gogo

これは基本的に petchの答え ですが、Qt 5.6で壊れたためにわずかな変更があります(これが一番の質問ヒットです)ので、すべてのクレジットは petch になります。

関数

bool copyPath(QString sourceDir, QString destinationDir, bool overWriteDirectory)
{
    QDir originDirectory(sourceDir);

    if (! originDirectory.exists())
    {
        return false;
    }

    QDir destinationDirectory(destinationDir);

    if(destinationDirectory.exists() && !overWriteDirectory)
    {
        return false;
    }
    else if(destinationDirectory.exists() && overWriteDirectory)
    {
        destinationDirectory.removeRecursively();
    }

    originDirectory.mkpath(destinationDir);

    foreach (QString directoryName, originDirectory.entryList(QDir::Dirs | \
                                                              QDir::NoDotAndDotDot))
    {
        QString destinationPath = destinationDir + "/" + directoryName;
        originDirectory.mkpath(destinationPath);
        copyPath(sourceDir + "/" + directoryName, destinationPath, overWriteDirectory);
    }

    foreach (QString fileName, originDirectory.entryList(QDir::Files))
    {
        QFile::copy(sourceDir + "/" + fileName, destinationDir + "/" + fileName);
    }

    /*! Possible race-condition mitigation? */
    QDir finalDestination(destinationDir);
    finalDestination.refresh();

    if(finalDestination.exists())
    {
        return true;
    }

    return false;
}

使用:

/*! Overwrite existing directories. */
bool directoryCopied = copyPath(sourceDirectory, destinationDirectory, true);

/*! Do not overwrite existing directories. */
bool directoryCopied = copyPath(sourceDirectory, destinationDirectory, false);
1

シェルコマンドスタイルAPIでファイルを操作するライブラリを作成しました。ファイルの再帰的なコピーをサポートし、さらにいくつかの条件を処理しました。

https://github.com/benlau/qtshell#cp

cp("-a", ":/*", "/target"); // copy all files from qrc resource to target path recursively

cp("tmp.txt", "/tmp");

cp("*.txt", "/tmp");

cp("/tmp/123.txt", "456.txt");

cp("-va","src/*", "/tmp");

cp("-a", ":resource","/target");
1
benlau