Files
hfut-bishe/client/core/persistence/JsonFileAtomic.cpp
T
2026-05-14 13:30:06 +08:00

63 lines
1.7 KiB
C++

#include "persistence/JsonFileAtomic.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
namespace core::persistence {
bool writeBytesAtomic(const QString& absolutePath, const QByteArray& bytes) {
if (absolutePath.isEmpty()) {
return false;
}
const QString parent = QFileInfo(absolutePath).absolutePath();
if (!QFileInfo(parent).exists()) {
QDir().mkpath(parent);
}
const QString tmpAbs = absolutePath + QStringLiteral(".tmp");
if (QFileInfo::exists(tmpAbs)) {
QFile::remove(tmpAbs);
}
QFile f(tmpAbs);
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return false;
}
const bool ok = f.write(bytes) == bytes.size();
f.close();
if (!ok || f.error() != QFile::NoError) {
QFile::remove(tmpAbs);
return false;
}
QFile::remove(absolutePath);
if (!QFile::rename(tmpAbs, absolutePath)) {
QFile::remove(tmpAbs);
return false;
}
return true;
}
bool writeJsonAtomic(const QString& absolutePath, const QJsonObject& obj, bool pretty) {
const QJsonDocument doc(obj);
const QByteArray bytes = doc.toJson(pretty ? QJsonDocument::Indented : QJsonDocument::Compact);
return writeBytesAtomic(absolutePath, bytes);
}
bool readJsonObject(const QString& absolutePath, QJsonObject& out) {
out = QJsonObject();
QFile f(absolutePath);
if (!f.open(QIODevice::ReadOnly)) {
return false;
}
const QByteArray data = f.readAll();
QJsonParseError err;
const QJsonDocument doc = QJsonDocument::fromJson(data, &err);
if (err.error != QJsonParseError::NoError || !doc.isObject()) {
return false;
}
out = doc.object();
return true;
}
} // namespace core::persistence