具有以下条件的文件中 read/write 对象的最佳方法是什么
What is the best way to read/write objects in a file with the following conditions
我愿意将对象存储在数据库中。目的是为了能够用程序读/写这些对象。要求如下:
- 使用 Qt 类 对象可以是 复杂的,例如
QList
、QString
... 甚至可以包含其他使用 Qt 的对象QObjects
- 数据库应该不能被人类读取或修改(没有文本文件,如果我使用sqlite数据库,它必须以某种方式加密)
- 我应该能够删除,通过名称读取对象并计算数据库中对象的数量,而无需将所有内容加载到内存中
我问了一个问题 here,用一个带有极简主义例子的 QDataStream
来做到这一点。但这似乎不是最好的方法。
对于为此目的而存在的解决方案,您有什么建议吗?
我试过以下但不满足要求:
- 使用
QtSQL
在 sqlite 中存储文本:但是数据可以通过使用 sqlitemanager 访问,例如,可以被人修改或删除。此外,我不知道如何存储 QList
或我创建并包含 QObject
的其他对象(例如,2 QList
)
- 使用
QDataStream
存储二进制数据:在这种情况下,我无法计算文件中的对象数量,在不加载内存中的整个文件。
如果你能给我一些建议或提供示例,我将不胜感激,即使示例是极简主义的。
我终于找到了解决方案,特别感谢 Igor Tandetnik 和主题 here
我还没有完全确定,有一个小瑕疵,因为我必须定义一个我不使用的用户 class 的对象,以便调用 readFromDB 函数从中生成我的对象分贝。
另一方面,我每次调用数据库时都会收到此错误消息 "QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed"。
无论如何,现在有点晚了,我认为它可能会对某些人有所帮助,所以我 post 下面是这个极简主义的不完美代码。我会在接下来的几天 post 进行更新。
再次感谢。
#include "QString"
#include "QFile"
#include "QDataStream"
#include "qdebug.h"
#include "QtSql"
#include "QSqlDatabase"
#include "qmessagebox.h"
class User
{
protected:
QString name;
QList<QString> childrens;
public:
QString getName(){ return name;}
QList<QString> getChildrens(){ return childrens;}
void setName(QString x) {name = x;}
void setChildrens(QList<QString> x) {childrens = x;}
friend QDataStream &operator<<(QDataStream &out, const User &t)
{
out << t.name << t.childrens;
return out;
}
friend QDataStream &operator>>(QDataStream &in, User &t)
{
QString inname;
QList<QString> inchildrens;
in >> inname >> inchildrens;
t.name = inname;
t.childrens = inchildrens;
return in;
}
QByteArray object2blob( const User& user )
{
QByteArray result;
QDataStream bWrite( &result, QIODevice::WriteOnly );
bWrite << user;
return result;
}
User blob2object( const QByteArray& buffer )
{
User result;
QDataStream bRead( buffer );
bRead >> result;
return result;
}
int saveToDB( const User& user )
{
QSqlDatabase myDB = QSqlDatabase::addDatabase("QSQLITE");
myDB.setDatabaseName( "file.db");
if (!myDB.open())
{
qDebug()<<"Failed to open SQL database of registered users";
}
else
{
qDebug()<<"Successfully opening SQL database of registered users";
QSqlQuery query;
query.prepare( "CREATE TABLE IF NOT EXISTS users (name TEXT, childrens BLOB)" );
if( !query.exec() )
{
qDebug() << query.lastError();
}
else
{
qDebug() << "Table created!";
query.prepare( "INSERT INTO users (name,childrens) VALUES (:name,:childrens)" );
query.bindValue(":name", name);
query.bindValue( ":childrens", object2blob(user) );
query.exec();
}
query.clear();
myDB.close();
}
QSqlDatabase::removeDatabase("UserConnection");
return 0;
}
User readFromDB( QString name )
{
User result;
QSqlDatabase myDB = QSqlDatabase::addDatabase("QSQLITE");
myDB.setDatabaseName( "file.db");
if (!myDB.open())
{
qDebug()<<"Failed to open SQL database of registered users";
}
else
{
QSqlQuery query;
query.prepare( "SELECT * FROM users WHERE name ='"+ name +"'" );
//query.bindValue( 0, name );
if ( query.exec() && query.next() ) {
result = blob2object( query.value( 1 ).toByteArray() );
}
query.clear();
myDB.close();
}
QSqlDatabase::removeDatabase("UserConnection");
qDebug()<<result.getChildrens();
return result;
}
};
////////////////////////////////////////////////////////////////
int main()
{
User u;
u.setName("Georges");
u.setChildrens(QList<QString>()<<"Jeanne"<<"Jean");
u.saveToDB(u);
User v;
v.setName("Alex");
v.setChildrens(QList<QString>()<<"Matthew");
v.saveToDB(v);
User w;
w.setName("Mario");
w.saveToDB(w);
User to_read; //to improve here
User a = to_read.readFromDB("Georges");
qDebug()<<a.getChildrens();
return 0;
}
我愿意将对象存储在数据库中。目的是为了能够用程序读/写这些对象。要求如下:
- 使用 Qt 类 对象可以是 复杂的,例如
QList
、QString
... 甚至可以包含其他使用 Qt 的对象QObjects
- 数据库应该不能被人类读取或修改(没有文本文件,如果我使用sqlite数据库,它必须以某种方式加密)
- 我应该能够删除,通过名称读取对象并计算数据库中对象的数量,而无需将所有内容加载到内存中
我问了一个问题 here,用一个带有极简主义例子的 QDataStream
来做到这一点。但这似乎不是最好的方法。
对于为此目的而存在的解决方案,您有什么建议吗?
我试过以下但不满足要求:
- 使用
QtSQL
在 sqlite 中存储文本:但是数据可以通过使用 sqlitemanager 访问,例如,可以被人修改或删除。此外,我不知道如何存储QList
或我创建并包含QObject
的其他对象(例如,2QList
) - 使用
QDataStream
存储二进制数据:在这种情况下,我无法计算文件中的对象数量,在不加载内存中的整个文件。
如果你能给我一些建议或提供示例,我将不胜感激,即使示例是极简主义的。
我终于找到了解决方案,特别感谢 Igor Tandetnik 和主题 here
我还没有完全确定,有一个小瑕疵,因为我必须定义一个我不使用的用户 class 的对象,以便调用 readFromDB 函数从中生成我的对象分贝。
另一方面,我每次调用数据库时都会收到此错误消息 "QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed"。
无论如何,现在有点晚了,我认为它可能会对某些人有所帮助,所以我 post 下面是这个极简主义的不完美代码。我会在接下来的几天 post 进行更新。
再次感谢。
#include "QString"
#include "QFile"
#include "QDataStream"
#include "qdebug.h"
#include "QtSql"
#include "QSqlDatabase"
#include "qmessagebox.h"
class User
{
protected:
QString name;
QList<QString> childrens;
public:
QString getName(){ return name;}
QList<QString> getChildrens(){ return childrens;}
void setName(QString x) {name = x;}
void setChildrens(QList<QString> x) {childrens = x;}
friend QDataStream &operator<<(QDataStream &out, const User &t)
{
out << t.name << t.childrens;
return out;
}
friend QDataStream &operator>>(QDataStream &in, User &t)
{
QString inname;
QList<QString> inchildrens;
in >> inname >> inchildrens;
t.name = inname;
t.childrens = inchildrens;
return in;
}
QByteArray object2blob( const User& user )
{
QByteArray result;
QDataStream bWrite( &result, QIODevice::WriteOnly );
bWrite << user;
return result;
}
User blob2object( const QByteArray& buffer )
{
User result;
QDataStream bRead( buffer );
bRead >> result;
return result;
}
int saveToDB( const User& user )
{
QSqlDatabase myDB = QSqlDatabase::addDatabase("QSQLITE");
myDB.setDatabaseName( "file.db");
if (!myDB.open())
{
qDebug()<<"Failed to open SQL database of registered users";
}
else
{
qDebug()<<"Successfully opening SQL database of registered users";
QSqlQuery query;
query.prepare( "CREATE TABLE IF NOT EXISTS users (name TEXT, childrens BLOB)" );
if( !query.exec() )
{
qDebug() << query.lastError();
}
else
{
qDebug() << "Table created!";
query.prepare( "INSERT INTO users (name,childrens) VALUES (:name,:childrens)" );
query.bindValue(":name", name);
query.bindValue( ":childrens", object2blob(user) );
query.exec();
}
query.clear();
myDB.close();
}
QSqlDatabase::removeDatabase("UserConnection");
return 0;
}
User readFromDB( QString name )
{
User result;
QSqlDatabase myDB = QSqlDatabase::addDatabase("QSQLITE");
myDB.setDatabaseName( "file.db");
if (!myDB.open())
{
qDebug()<<"Failed to open SQL database of registered users";
}
else
{
QSqlQuery query;
query.prepare( "SELECT * FROM users WHERE name ='"+ name +"'" );
//query.bindValue( 0, name );
if ( query.exec() && query.next() ) {
result = blob2object( query.value( 1 ).toByteArray() );
}
query.clear();
myDB.close();
}
QSqlDatabase::removeDatabase("UserConnection");
qDebug()<<result.getChildrens();
return result;
}
};
////////////////////////////////////////////////////////////////
int main()
{
User u;
u.setName("Georges");
u.setChildrens(QList<QString>()<<"Jeanne"<<"Jean");
u.saveToDB(u);
User v;
v.setName("Alex");
v.setChildrens(QList<QString>()<<"Matthew");
v.saveToDB(v);
User w;
w.setName("Mario");
w.saveToDB(w);
User to_read; //to improve here
User a = to_read.readFromDB("Georges");
qDebug()<<a.getChildrens();
return 0;
}