QT实现对数据文本保存的办法及其操作

(1)文本文件(QTextStream流):文件内容是可读的文本字符

(2)数据文件(QDataStream流):文件内容是直接的二进制数据

QT对文本操作方式

1、QFile类,该类支持 对文件或者是数据文件的读写,提供的接口如下:
  ①qint64 read(char* data, qint64 maxSize);

  ②QByteArray read(qint64 maxSize);

  ③qint64 write(const char* data, qint64 maxSize);

  ④qint64 write(const QByteArray& byteArray);
该类暴露出来的缺点就是需要对数据类型的强制转换;

直接用QFile读写的实例代码

#include <QCoreApplication>
#include <QFile>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QFile file("C:/Users/SantaClaus/Desktop/test.hex");

    if (file.open(QIODevice::WriteOnly)) //打开方式:可读、二进制方式
    {
        QString name = "SantaClaus";
        double value = 3.14;

        //按二进制写入时,须进行类型转换,这也是QFile使用上比较麻烦的地方
        file.write(name.toStdString().c_str()); //参数为char*,须转换
        file.write(reinterpret_cast<char*>(&value), sizeof(value));

        file.close();
    }

    if(file.open(QIODevice::ReadOnly)) //只读、二进制方式
    {
        QString name ="";
        double value = 0;

       //read的返回值为QByteArray,当赋值给QString变量类型时进行自动转换
        //以下语句也可以写成name = file.read(10);
        name = QString(file.read(10));
        file.read(reinterpret_cast<char*>(&value), sizeof(value));

        file.close();

        qDebug() << name;
        qDebug() << value;
    }

    return a.exec();
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2、QFile结合使用辅助的文件流QTextStream;
QTextStream:写入的数据全部转换为可读文件

#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QDebug>
void textStream_test(QString f)
{
    QFile file(f);

    if(file.open(QIODevice::WriteOnly | QIODevice::Text)) //以文本文式写入
    {
        QTextStream out(&file);

        out << QString("SantaClaus") << endl;
        out << QString("Result: ") << endl;
        //以下故意输入多种类型的数据,但都被自动转换为QString类型,不需要显式转换!
        out << 5 << "*" << 6 << '=' << 5*6 << endl;

        file.close();
    }

    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);

        while( !in.atEnd()) //未到文件尾
        {
            QString line = in.readLine();
            qDebug() << line;
        }

        file.close();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

3、QFile类结合使用数据文本流QDataStream;
QDataStream:写入的数据根据类型转换为二进制数据;
但值得注意的是:
A、不同Qt版本的数据流文件格式可能不同,当数据流文件需要在不同版本的Qt程序间传递数据时,需要考虑版本问题。
B、相关函数

    void setVersion(int v); //设置读写版本号

    int version() const //获取读写版本号

#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QDebug>
void dataStream_test(QString f)
{
    QFile file(f);

    if(file.open(QIODevice::WriteOnly)) //以二进制方式打开
    {
        QDataStream out(&file);

        //设置数据流的版本,以便在不同版本的Qt间进行数据传递
        out.setVersion(QDataStream::Qt_5_6);

        out << QString("SantaClaus");
        out << QString("Result: ");
        out << 3.14;

        file.close();
    }

    if (file.open(QIODevice::ReadOnly))
    {
        QDataStream in(&file);
        QString name = "";
        QString result = "";
        double value = 0;

        in.setVersion(QDataStream::Qt_5_6);

        in >> name;
        in >> result;
        in >> value;

        qDebug() << name;
        qDebug() << result;
        qDebug() << value;
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

小结

(1)Qt中的文件辅助类用于方便读写操作

(2)QTextStream用于文本数据的快速读写

(3)QDataStream用于二进制数据的快速读写

(4)QDataStream的文件格式与Qt版本相关

(5)数据格式文件在程序间传递时,需要考虑版本问题

流使用实用技巧

最近在搞个小项目,用QT结合OpenCV做开发,需要用到将程序运行的某些参数保存下来,采用的是文本保存,这一次遇到的都是一些浮点的类型,一开始想让这些浮点类型转换为字符类型QString,这样的方法也可以行得通,但是会损失一小些精度,且操作繁琐,效率也不高,想到了文本流好像直接支持类型的操作,一开始尝试了下,但是达不到我想要的理想,需要做另外一些的字符分割操作。反反复复对文件进行了操作,不断的调试,最后了解到了文件流操作的规律。
起初的代码:

保存数据到文本文件中。

#define  SAVE_DATA          "J_SAVE.dat"
double XX_Angle;
CvPoint2D32f OffsetPos;

void MainWindow::saveData()
{
    QFile ExpandData(SAVE_DATA);
    if(ExpandData.open(QIODevice::WriteOnly))
    {
        /*文本输出流,用于保存数据*/
        QTextStream Out(&ExpandData);
        Out << XX_Angle;
        Out << OffsetPos.x;
        Out << OffsetPos.y;

        ExpandData.close();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

从文本文件上加载之前保存的数据

#define  SAVE_DATA          "J_SAVE.dat"
double XX_Angle;
CvPoint2D32f OffsetPos;

void MainWindow::loadData()
{
    QFile ExpandData(SAVE_DATA);
    if(ExpandData.open(QIODevice::ReadOnly))
    {
        /*文本输出流,用于保存数据*/
        QTextStream In(&ExpandData);

        In >> XX_Angle;
        In >> OffsetPos.x;
        In >> OffsetPos.y;

        ExpandData.close();
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

上面的代码测试的结果是:写和读不对称,写入的东西以同样形式,数据类型对称的形式来读取不能实现对称。最后找到原因是文本文件流一次流读取是以一个空格为结束的,找到这个规律之后,我在写入的数据的时候做了一些额外操作,添加空格。
下面是调通之后的代码,可以尽情享用C++ 流带来的方便快速。

#define  SAVE_DATA          "J_SAVE.dat"
double XX_Angle;
CvPoint2D32f OffsetPos;
/*实现保存程序运行的数据*/
void MainWindow::saveData()
{
    QFile ExpandData(SAVE_DATA);
    if(ExpandData.open(QIODevice::WriteOnly))
    {
        /*文本输出流,用于保存数据*/
        QTextStream Out(&ExpandData);
        /*加入空格的好处是以流的形式读取恰好是相反的操作,这样一来方便快速对参数的读取*/
        Out << XX_Angle;
        Out << ' ';
        Out << OffsetPos.x;
        Out << ' ';
        Out << OffsetPos.y;

    ExpandData<span class="hljs-preprocessor">.close</span>()<span class="hljs-comment">;</span>
}

}
/加载程序运行时保存的数据/
void MainWindow::loadData()
{
QFile ExpandData(SAVE_DATA);
if(ExpandData.open(QIODevice::ReadOnly))
{
/文本输出流,用于保存数据/
QTextStream In(&ExpandData);

    <span class="hljs-keyword">In</span> &gt;&gt; XX_Angle<span class="hljs-comment">;</span>
    <span class="hljs-keyword">In</span> &gt;&gt; OffsetPos<span class="hljs-preprocessor">.x</span><span class="hljs-comment">;</span>
    <span class="hljs-keyword">In</span> &gt;&gt; OffsetPos<span class="hljs-preprocessor">.y</span><span class="hljs-comment">;</span>

    ExpandData<span class="hljs-preprocessor">.close</span>()<span class="hljs-comment">;</span>
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

  • 4
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt中使用数据库可以通过Qt自带的Qt SQL模块来实现。下面是一个简单的示例代码,演示了如何使用SQLite数据保存用户数据: 首先,确保已在项目文件(.pro)中添加了对Qt SQL模块的引用: ```plaintext QT += sql ``` 然后,可以按照以下步骤使用数据库: 1. 引入必要的头文件: ```cpp #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError> ``` 2. 创建数据库连接并打开数据库: ```cpp QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("mydatabase.db"); // 指定数据库文件名 if (!db.open()) { qDebug() << "无法建立数据库连接!"; return; } ``` 3. 创建数据表(如果尚未存在): ```cpp QSqlQuery query; query.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)"); if (query.lastError().isValid()) { qDebug() << "无法创建数据表!" << query.lastError(); return; } ``` 4. 插入用户数据数据库: ```cpp QString name = "John"; int age = 30; query.prepare("INSERT INTO users (name, age) VALUES (:name, :age)"); query.bindValue(":name", name); query.bindValue(":age", age); if (!query.exec()) { qDebug() << "无法插入数据!" << query.lastError(); return; } ``` 5. 查询数据库中的用户数据: ```cpp query.exec("SELECT * FROM users"); while (query.next()) { int id = query.value("id").toInt(); QString name = query.value("name").toString(); int age = query.value("age").toInt(); qDebug() << "ID:" << id << "Name:" << name << "Age:" << age; } ``` 6. 关闭数据库连接: ```cpp db.close(); ``` 以上代码示例了如何使用Qt SQL模块在SQLite数据库中保存用户数据。你可以根据需要修改表结构、插入数据和查询数据的逻辑。同时,Qt SQL模块也支持其他类型的数据库,如MySQL、PostgreSQL等,只需更改数据库驱动和连接参数即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值