clean: utilize QSaveFile and improve config/favorite/history file saving

This commit is contained in:
shenleban tongying 2024-03-25 08:09:55 -04:00
parent e0d09302d2
commit 3187fdeb64
7 changed files with 32 additions and 84 deletions

View file

@ -290,7 +290,6 @@ HEADERS += \
src/audioplayerinterface.hh \ src/audioplayerinterface.hh \
src/btreeidx.hh \ src/btreeidx.hh \
src/chunkedstorage.hh \ src/chunkedstorage.hh \
src/common/atomic_rename.hh \
src/common/base_type.hh \ src/common/base_type.hh \
src/common/ex.hh \ src/common/ex.hh \
src/common/file.hh \ src/common/file.hh \
@ -419,7 +418,6 @@ SOURCES += \
src/audioplayerfactory.cc \ src/audioplayerfactory.cc \
src/btreeidx.cc \ src/btreeidx.cc \
src/chunkedstorage.cc \ src/chunkedstorage.cc \
src/common/atomic_rename.cc \
src/common/file.cc \ src/common/file.cc \
src/common/filetype.cc \ src/common/filetype.cc \
src/common/folding.cc \ src/common/folding.cc \

View file

@ -1,42 +0,0 @@
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include "atomic_rename.hh"
#include <QtGlobal>
#include <QVector>
#include <string> // for wchar_t
#include <QFile>
#include <QDir>
#ifdef Q_OS_WIN32
#include <windows.h>
#endif
#include <stdio.h>
bool renameAtomically( QString const & oldName, QString const & newName )
{
#ifdef Q_OS_WIN32
QString srcFile( QDir::toNativeSeparators( oldName ) );
QVector< wchar_t > srcFileW( srcFile.size() + 1 );
srcFileW[ srcFile.toWCharArray( srcFileW.data() ) ] = 0;
QString destFile( QDir::toNativeSeparators( newName ) );
QVector< wchar_t > destFileW( destFile.size() + 1 );
destFileW[ destFile.toWCharArray( destFileW.data() ) ] = 0;
if ( !MoveFileExW( srcFileW.data(), destFileW.data(), MOVEFILE_REPLACE_EXISTING ) )
return false;
#else
if ( rename( QFile::encodeName( QDir::toNativeSeparators( oldName ) ).data(),
QFile::encodeName( QDir::toNativeSeparators( newName ) ).data() ) )
return false;
#endif
return true;
}

View file

@ -1,14 +0,0 @@
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#ifndef __ATOMIC_RENAME_HH_INCLUDED__
#define __ATOMIC_RENAME_HH_INCLUDED__
#include <QString>
/// Performs an atomic rename of file, from oldBame to newName. If newName
/// exists, it gets overwritten. Names should feature Qt-style separators
/// (straight slashes). Returns true on success, false on failure.
bool renameAtomically( QString const & oldName, QString const & newName );
#endif

View file

@ -3,7 +3,7 @@
#include "config.hh" #include "config.hh"
#include "folding.hh" #include "folding.hh"
#include <QDir> #include <QSaveFile>
#include <QFile> #include <QFile>
#include <QtXml> #include <QtXml>
#include <QApplication> #include <QApplication>
@ -17,8 +17,6 @@
#include <stdint.h> #include <stdint.h>
#include "atomic_rename.hh"
#include <QStandardPaths> #include <QStandardPaths>
#if defined( HAVE_X11 ) #if defined( HAVE_X11 )
@ -1310,7 +1308,7 @@ void saveGroup( Group const & data, QDomElement & group )
void save( Class const & c ) void save( Class const & c )
{ {
QFile configFile( getConfigFileName() + ".tmp" ); QSaveFile configFile( getConfigFileName() );
if ( !configFile.open( QFile::WriteOnly ) ) if ( !configFile.open( QFile::WriteOnly ) )
throw exCantWriteConfigFile(); throw exCantWriteConfigFile();
@ -2233,14 +2231,9 @@ void save( Class const & c )
hd.appendChild( opt ); hd.appendChild( opt );
} }
QByteArray result( dd.toByteArray() ); configFile.write( dd.toByteArray() );
if ( !configFile.commit() )
if ( configFile.write( result ) != result.size() )
throw exCantWriteConfigFile(); throw exCantWriteConfigFile();
configFile.close();
renameAtomically( configFile.fileName(), getConfigFileName() );
} }
QString getConfigFileName() QString getConfigFileName()

View file

@ -3,8 +3,9 @@
#include "history.hh" #include "history.hh"
#include "config.hh" #include "config.hh"
#include "atomic_rename.hh"
#include <QFile> #include <QFile>
#include <QSaveFile>
#include <QDebug>
History::History( unsigned size, unsigned maxItemLength_ ): History::History( unsigned size, unsigned maxItemLength_ ):
maxSize( size ), maxSize( size ),
@ -117,7 +118,7 @@ bool History::save()
if ( !dirty ) if ( !dirty )
return true; return true;
QFile file( Config::getHistoryFileName() + ".tmp" ); QSaveFile file( Config::getHistoryFileName() );
if ( !file.open( QFile::WriteOnly | QIODevice::Text ) ) if ( !file.open( QFile::WriteOnly | QIODevice::Text ) )
return false; return false;
@ -136,11 +137,13 @@ bool History::save()
return false; return false;
} }
file.close(); if ( file.commit() ) {
dirty = false;
return true;
}
dirty = false; qDebug() << "Failed to save history file";
return false;
return renameAtomically( file.fileName(), Config::getHistoryFileName() );
} }
void History::clear() void History::clear()

View file

@ -21,12 +21,12 @@
#endif #endif
#include "termination.hh" #include "termination.hh"
#include "atomic_rename.hh"
#include <QByteArray> #include <QByteArray>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QFile> #include <QFile>
#include <QMessageBox> #include <QMessageBox>
#include <QString> #include <QString>
#include <QStringBuilder>
#include <QtWebEngineCore/QWebEngineUrlScheme> #include <QtWebEngineCore/QWebEngineUrlScheme>
#include "gddebug.hh" #include "gddebug.hh"
@ -498,7 +498,10 @@ int main( int argc, char ** argv )
return -1; return -1;
QString configFile = Config::getConfigFileName(); QString configFile = Config::getConfigFileName();
renameAtomically( configFile, configFile + ".bad" ); QFile::rename( configFile,
configFile % QStringLiteral( "." )
% QDateTime::currentDateTime().toString( QStringLiteral( "yyyyMMdd_HHmmss" ) )
% QStringLiteral( ".bad" ) );
continue; continue;
} }
break; break;

View file

@ -9,12 +9,15 @@
#include <QMessageBox> #include <QMessageBox>
#include <QtAlgorithms> #include <QtAlgorithms>
#include <QMap> #include <QMap>
#include <QSaveFile>
#include <QStringBuilder>
#include <QDebug>
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
#include "favoritespanewidget.hh" #include "favoritespanewidget.hh"
#include "gddebug.hh" #include "gddebug.hh"
#include "atomic_rename.hh"
#include "globalbroadcaster.hh" #include "globalbroadcaster.hh"
/************************************************** FavoritesPaneWidget *********************************************/ /************************************************** FavoritesPaneWidget *********************************************/
@ -624,7 +627,10 @@ void FavoritesModel::readData()
dom.clear(); dom.clear();
favoritesFile.close(); favoritesFile.close();
renameAtomically( m_favoritesFilename, m_favoritesFilename + ".bak" ); QFile::rename( m_favoritesFilename,
m_favoritesFilename % QStringLiteral( "." )
% QDateTime::currentDateTime().toString( QStringLiteral( "yyyyMMdd_HHmmss" ) )
% QStringLiteral( ".bad" ) );
} }
else else
favoritesFile.close(); favoritesFile.close();
@ -642,7 +648,7 @@ void FavoritesModel::saveData()
if ( !dirty ) if ( !dirty )
return; return;
QFile tmpFile( m_favoritesFilename + ".tmp" ); QSaveFile tmpFile( m_favoritesFilename );
if ( !tmpFile.open( QFile::WriteOnly ) ) { if ( !tmpFile.open( QFile::WriteOnly ) ) {
gdWarning( "Can't write favorites file, error: %s", tmpFile.errorString().toUtf8().data() ); gdWarning( "Can't write favorites file, error: %s", tmpFile.errorString().toUtf8().data() );
return; return;
@ -661,11 +667,12 @@ void FavoritesModel::saveData()
return; return;
} }
tmpFile.close(); if ( tmpFile.commit() ) {
if ( renameAtomically( tmpFile.fileName(), m_favoritesFilename ) )
dirty = false; dirty = false;
}
else {
qDebug() << "Failed to save favorite file";
}
dom.clear(); dom.clear();
} }