Hello,
 
I  am trying to use QSaveFile on wec7 but commit() fails
1. in ram based file system if the file does not already exist.
2. in flash based file system , it fails always.
while analyzing the problem i found this:
QSaveFile::commit()  has this code
       // atomically replace old file with new file
        // Can't use QFile::rename for that, must use the file engine directly
        Q_ASSERT(d->fileEngine);
        if (!d->fileEngine->renameOverwrite(d->finalFileName)) {
the implementation of renameOverwrite for wince look like this:
bool QFSFileEngine::renameOverwrite(const QString &newName)
{
    Q_D(QFSFileEngine);
#if defined(Q_OS_WINCE)
    // Windows Embedded Compact 7 does not have MoveFileEx, simulate it with  the following sequence:
    //   1. DeleteAndRenameFile  (Should work on RAM FS when both files exist)
    //   2. DeleteFile/MoveFile  (Should work on all file systems)
    //
    // DeleteFile/MoveFile fallback implementation violates atomicity, but it is more acceptable than
    // alternative CopyFile/DeleteFile sequence for the following reasons:
    //
    //  1. DeleteFile/MoveFile is way faster than CopyFile/DeleteFile and thus more atomic.
    //  2. Given the intended use case of this function in QSaveFile, DeleteFile/MoveFile sequence will
    //     delete the old content, but leave a file "filename.ext.XXXXXX" in the same directory if MoveFile fails.
    //     With CopyFile/DeleteFile sequence, it can happen that new data is partially copied to target file
    //     (because CopyFile is not atomic either), thus leaving *some* content to target file.
    //     This makes the need for application level recovery harder to detect than in DeleteFile/MoveFile
    //     sequence where target file simply does not exist.
    //
    bool ret = ::DeleteAndRenameFile((wchar_t*)QFileSystemEntry(newName).nativeFilePath().utf16(),
                                     (wchar_t*)d->fileEntry.nativeFilePath().utf16()) != 0;
    if (!ret) {
        ret = ::DeleteFile((wchar_t*)d->fileEntry.nativeFilePath().utf16()) != 0;
        if (ret)
            ret = ::MoveFile((wchar_t*)d->fileEntry.nativeFilePath().utf16(),
                             (wchar_t*)QFileSystemEntry(newName).nativeFilePath().utf16()) != 0;
    }
so in a ram based file system DeleteAndRenameFile works only if source AND destination exist. QSaveFile does not obey to this and renameOverwrite does also not care to create a dest file if it does not exists, even that the programmer knew this restriction as he wrote that himself in the comments.
in a flash or fat based file system DeleteAndRenameFile  as expsected but then 
the source file is deleted and then it is renamed. that sound like doing it in the wrong order.
Regards,
Gunnar Roth
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to