refs #545 CAtomicFile used in CValueCache to avoid corruption in case serialization is interrupted.

This commit is contained in:
Mathew Sutcliffe
2016-01-10 23:39:26 +00:00
parent 956d393bb1
commit f9de444a53
3 changed files with 162 additions and 7 deletions

View File

@@ -0,0 +1,61 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_ATOMICFILE_H
#define BLACKMISC_ATOMICFILE_H
#include <QFile>
#include "blackmisc/blackmiscexport.h"
namespace BlackMisc
{
/*!
* A subclass of QFile which writes to a temporary file while it is open, then renames the file
* when it is closed, so that it overwrites the target file as a single, atomic transaction.
*
* If the application crashes while data is still being written, the original file is unchanged.
*/
class BLACKMISC_EXPORT CAtomicFile : public QFile
{
public:
//! \copydoc QFile::QFile(const QString &)
CAtomicFile(const QString &filename) : QFile(filename) {}
//! \copydoc QFile::~QFile
~CAtomicFile() { close(); }
//! \copydoc QFile::open
//! Just before opening the file, the filename is changed so we actually write to a temporary file.
virtual bool open(OpenMode mode) override;
//! \copydoc QFileDevice::close
//! After closing the file, it is renamed so that it overwrites the target file.
virtual void close() override;
//! Calls close() and returns false if there was an error at any stage.
bool checkedClose();
//! \copydoc QFileDevice::error
FileError error() const;
//! \copydoc QFileDevice::unsetError
void unsetError();
private:
static QString randomSuffix();
void replaceOriginal();
QString m_originalFilename;
bool m_renameError = false;
};
}
#endif