From 59847f4f30cd877161a76b459446e5b1ca912cce Mon Sep 17 00:00:00 2001 From: Felix Geyer Date: Mon, 22 Oct 2012 17:48:13 +0200 Subject: [PATCH] Make QSaveFile work on Windows when the target file already exists. --- src/core/qsavefile.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/core/qsavefile.cpp b/src/core/qsavefile.cpp index 26ba1cb26..51ef0c339 100644 --- a/src/core/qsavefile.cpp +++ b/src/core/qsavefile.cpp @@ -288,30 +288,33 @@ bool QSaveFile::commit() d->tempFile = 0; return false; } - // atomically replace old file with new file - // Can't use QFile::rename for that, must use the file engine directly - // But that's not available in Qt5, nor is QTemporaryFileEngine - // (used by the Qt5-QFileDevice-based QSaveFile). - // So we have to do it by hand (non portable) for now. d->tempFile->close(); -#if 1 +#ifdef Q_OS_WIN + // On Windows QAbstractFileEngine::rename() fails if the the target exists, + // so we have to rename the target. + // Ideally the winapi ReplaceFile() method should be used. + QString bakname = d->fileName + "~"; + QFile::remove(bakname); + QFile::rename(d->fileName, bakname); +#endif QAbstractFileEngine* fileEngine = d->tempFile->fileEngine(); Q_ASSERT(fileEngine); if (!fileEngine->rename(d->fileName)) { d->error = fileEngine->error(); setErrorString(fileEngine->errorString()); -#else - if (::rename(QFile::encodeName(d->tempFile->fileName()).constData(), QFile::encodeName(d->fileName).constData()) != 0) { - d->error = QFile::RenameError; - setErrorString(QString::fromLocal8Bit(strerror(errno))); -#endif d->tempFile->remove(); delete d->tempFile; d->tempFile = 0; +#ifdef Q_OS_WIN + QFile::rename(bakname, d->fileName); +#endif return false; } delete d->tempFile; d->tempFile = 0; +#ifdef Q_OS_WIN + QFile::remove(bakname); +#endif return true; }