あるドライブから別のドライブにディレクトリをコピーしたいと考えています。選択したディレクトリには、多くのサブディレクトリとファイルが含まれています。
Qtを使用して同じことを実装するにはどうすればよいですか?
あるドライブから別のドライブにディレクトリをコピーしたいと考えています。選択したディレクトリには、多くのサブディレクトリとファイルが含まれています。
Qtを使用して同じことを実装するにはどうすればよいですか?
手動で、次のことを行うことができます。
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)。次に、次のように宛先リストから新しいソース ディレクトリにファイルのコピーを開始できます。
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;
}
}
}
}
それだけです。幸運を!
私は似たようなものが欲しくて、(無駄に)グーグルで調べていたので、これが私がしなければならない場所です:
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());
}
これは、リンクと特別なファイルを処理しません。
難しい方法。すべてのファイルを個別にコピーします。
QDir::entryList()
ディレクトリのコンテンツを反復処理するために使用しますQDir::cd()
およびを使用QDir::cdUp()
して、ディレクトリに出入りします QDir::mkdir()
とを使用QDir::mkpath()
して、新しいフォルダ ツリーを作成します。 QFile::copy()
、実際のファイルをコピーするために使用しますこれを試して:
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;
}
macOS の App-Bundles で問題が発生したため、QDirIterator を使用した解決策を次に示します。
void copyAndReplaceFolderContents(const QString &fromDir, const QString &toDir, bool copyAndRemove = false) {
QDirIterator it(fromDir, QDirIterator::Subdirectories);
QDir dir(fromDir);
const int absSourcePathLength = dir.absoluteFilePath(fromDir).length();
while (it.hasNext()){
it.next();
const auto fileInfo = it.fileInfo();
if(!fileInfo.isHidden()) { //filters dot and dotdot
const QString subPathStructure = fileInfo.absoluteFilePath().mid(absSourcePathLength);
const QString constructedAbsolutePath = toDir + subPathStructure;
if(fileInfo.isDir()){
//Create directory in target folder
dir.mkpath(constructedAbsolutePath);
} else if(fileInfo.isFile()) {
//Copy File to target directory
//Remove file at target location, if it exists. Otherwise QFile::copy will fail
QFile::remove(constructedAbsolutePath);
QFile::copy(fileInfo.absoluteFilePath(), constructedAbsolutePath);
}
}
}
if(copyAndRemove)
dir.removeRecursively();
}