diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 263806c542d..c645e57bdb6 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -667,46 +667,30 @@ QFile::rename(const QString &newName) return false; } - QFile out(newName); - if (open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { - if (out.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered)) { - bool error = false; - char block[4096]; - qint64 bytes; - while ((bytes = read(block, sizeof(block))) > 0) { - if (bytes != out.write(block, bytes)) { - d->setError(QFile::RenameError, out.errorString()); - error = true; - break; - } - } - if (bytes == -1) { - d->setError(QFile::RenameError, errorString()); - error = true; - } - if (!error) { - if (!remove()) { - d->setError(QFile::RenameError, tr("Cannot remove source file")); - error = true; - } - } - if (error) { - out.remove(); - } else { - d->fileEngine->setFileName(newName); - setPermissions(permissions()); - unsetError(); - setFileName(newName); - } - close(); - return !error; +#if QT_CONFIG(temporaryfile) + // copy the file to the destination first + if (d->copy(newName)) { + // succeeded, remove the original + if (!remove()) { + d->setError(QFile::RenameError, tr("Cannot remove source file: %1").arg(errorString())); + QFile out(newName); + // set it back to writable so we can delete it + out.setPermissions(ReadUser | WriteUser); + out.remove(newName); + return false; } - close(); - d->setError(QFile::RenameError, - tr("Cannot open destination file: %1").arg(out.errorString())); + d->fileEngine->setFileName(newName); + unsetError(); + setFileName(newName); + return true; } else { + // change the error type but keep the string d->setError(QFile::RenameError, errorString()); } +#else + // copy the error from the engine rename() above + d->setError(QFile::RenameError, d->fileEngine->errorString()); +#endif } return false; } diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 306dda14690..184853b28d7 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -3026,6 +3026,11 @@ void tst_QFile::renameFallback() QFile::remove("file-rename-destination.txt"); QVERIFY(!file.rename("file-rename-destination.txt")); +#ifdef Q_OS_WIN + // wait for the file to disappear + QTRY_VERIFY_WITH_TIMEOUT(!QFile::exists("file-rename-destination.txt"), + std::chrono::seconds(1)); +#endif QVERIFY(!QFile::exists("file-rename-destination.txt")); QVERIFY(!file.isOpen()); }