QT开发--文件的读写操作

第十三章 文件的读写操作

Qt提供两种读写纯文本文件的方法:

1、直接使用 QFile 类的IO功能;

2、结合 QFileQTextStream,利用流(Stream)进行操作。

13.1 文件读操作

13.1.1 使用QFile类

        Qt封装了QFile类,方便我们对文件进行操作,可以按照如下的步骤进行:

        - 使用QFile加载文件对象

        - 打开文件 file.open(打开方式)

        - 操作文件

        - 关闭文件 file.close()

实例:点击读写文件按钮,读取文件内容到 textEdit中

设置ui界面

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MyDialog md;
    // 点击选取文件按钮,弹出文件对话框
    md.connect(md.ui->pushButton,&QPushButton::clicked,[&]() {
        QString path=  QFileDialog::getOpenFileName(md.ui->pushButton, //对话框部件
                                                            "打开文件", //对话框标题
                                              "C:/Users/WFD/Desktop"); //默认打开路径,找不到就是工作目录
        // 将路径显示在lineEdit中
        md.ui->textEdit_2->setText(path);

        // 读取文件内容,放入textEdit中
        QFile file(path);//参数就是文件的路径
        // 设置打开方式
        file.open(QIODevice::ReadOnly);
        // 用QByteArray类去接收读取的信息
        QByteArray array=file.readAll();
        // 将读取到的数据放入textEdit中
        md.ui->textEdit->setText(array);
        // 关闭文件对象
        file.close();
    });
    md.show();
       // 进入Qt应用程序的事件循环
       return app.exec();
}
按钮结合QFileDialog::getOpenFileName实现打开文件目录

        QFile::open() 函数打开文件时需要传递 `QIODevice::OpenModeFlag` 枚举类型的参数,决定文件以什么方式打开。

QIODevice::ReadOnly  	//以只读方式打开文件,用于载入文件。
QIODevice::WriteOnly  	//以只写方式打开文件,用于保存文件。
QIODevice::ReadWrite 	//以读写方式打开。
QIODevice::Append  		//以添加模式打开,新写入文件的数据添加到文件尾部。
QIODevice::Truncate 	//以截取方式打开文件,文件原有的内容全部被删除。
QIODevice::Text       	//以文本方式打开文件,读取时“\n”被自动翻译为换行符,
                        //写入时字符串结束符会自动翻译为系统平台的编码,
                        //如 Windows 平台下是“\r\n”。

//这些取值可以组合,例如 QIODevice::ReadOnly | QIODevice::Text 表示以只读和文本方式打开文件。

        操作文件时,若以只读方式打开文本文件,可用QFile::readAll()一次读取全部内容,

        返回QByteArray,需转为QString查看。或使用readLine()逐行读取,并用file.atEnd()判断是否结束:

QByteArray array;  
while (!file.atEnd()) {  
    array += file.readLine();  
}

13.1.2 使用QTextStream类

        如果操作的是文本文件,Qt还专门封装了一个处理文本流的QTextStream类,我们可以用它来读取文本内容。

// 点击选取文件按钮,弹出文件对话框
connect(ui->pushButton,&QPushButton::clicked,[=]() {
	QString path =  QFileDialog::getOpenFileName(this,"打开文件","C:/Users/WFD/Desktop");
	// 将路径放在lineEdit中
	ui->lineEdit->setText(path);
	// 读取文件内容,放入textEdit中
	QFile file(path);	// 参数就是文件的路径
	// 设置打开方式
	file.open(QIODevice::ReadOnly);
	// 用QTextStream类去读取文本信息
	QTextStream QS(&file);
	// 用QString类去接收读取的信息
	QString array = QS.readAll();
	// 将读取到的数据放入textEdit中
	ui->textEdit->setText(array);
	// 关闭文件对象
	file.close();
}

13.2 文件写操作

13.2.1 使用QFile类

        使用QFile同样可以对文件进行写操作:

//获取要写入的文件路径
QString path = QFileDialog::getSaveFileName(  
    this,        // 父窗口  
    "保存",      // 对话框标题  
    "D:\\temp\\",// 默认目录  
    "TXT (*.txt)"// 文件过滤器  
);

QFile file(path);  
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {  
    file.write("你好");   //写入
    file.close();  
} else {  
    // 处理文件打开失败的情况  
    qDebug() << "无法打开文件以写入";  
}

13.2.2 使用QTextStream类

        QTextStream类对操作符进行了重载,我们可以通过 << 操作符将字符串流入文本文件:

QString path = QFileDialog::getSaveFileName(this, //父指针
                                           "保存",//对话窗口名称
                                     "D:\\temp\\",//要保存的路径
                                    "TXT(*.txt)");//文件过滤器  
QFile file(path);  
file.open(QIODevice::WriteOnly | QIODevice::Text);  
QTextStream out(&file);  
QString str = "你好";  
out << str;  
file.close();

13.3 文件信息读取

        Qt提供了QFileInfo类,用于获取文件的元数据,包括文件大小后缀名、创建及最后修改时间等。

QString path = QFileDialog::getOpenFileName(this, //父窗口
                                      "打开文件",  //窗口名
                                   "D:\\temp\\");  //路径
QFileInfo file(path);  
qDebug() << "文件名" << file.fileName();  
qDebug() << "后缀名" << file.suffix();  
qDebug() << "文件大小" << file.size();  
qDebug() << "创建日期" << file.birthTime().toString("yyyy/MM/dd hh:mm:ss");  
qDebug() << "最后修改" << file.lastModified().toString("yyyy/MM/dd hh:mm:ss");

编码转换

        QString 转 QByteArray: 使用 QString.toUtf8()

QString qstr = "example";  
QByteArray byteArray = qstr.toUtf8();

        QByteArray 转 std::string: 使用 QByteArray.toStdString()

QByteArray byteArray = ...;  
std::string stdStr = byteArray.toStdString();

        std::string 转 char *: 使用 std::string.c_str()(注意:返回的是指向内部数据的常量指针,需确保std::string在指针使用期间不被修改或销毁)。

std::string stdStr = "example";  
const char* cStr = stdStr.c_str();  
// 若需要非const char*,可考虑复制一份数据:  
char* writableCStr = new char[stdStr.size() + 1];  
std::strcpy(writableCStr, stdStr.c_str());  
// 使用后需删除:  
delete[] writableCStr;

常用静态函数

        QFileDialog::getOpenFileName(): 弹出文件选择对话框,返回用户选择的文件路径

QString filePath = QFileDialog::getOpenFileName(this, "打开文件", "D:\\temp\\");

        QFileDialog::getExistingDirectory(): 弹出目录选择对话框,返回用户选择的目录路径

QString dirPath = QFileDialog::getExistingDirectory(this, "选择目录", "D:\\temp\\");

        QFileDialog::getSaveFileName(): 弹出文件保存对话框,返回用户指定的保存文件路径

QString savePath = QFileDialog::getSaveFileName(this,     //父窗口
                                           "保存文件",     //窗口名称
                                         "D:\\temp\\",     //打开的目录i
                                       "TXT (*.txt)");     //文件过滤,只显示.txt后缀

13.4 QT配置ini文件

13.4.1 ini文件介绍

        .ini 文件是初始化文件,用于配置应用软件以满足用户需求。

        它广泛存在于多个操作系统中,并可通过应用程序的图形界面进行操作,而无需直接编辑文件。.ini 文件可存储软件信息和注册表信息等。

13.4.2 ini文件格式

        ini 文件构成。

        方括号 [ ] 包围,如 [Section1 Name],用于区分不同用途的参数区

        通过等号 = 连接,如 KeyName1=value1。

        注解使用分号 ;,其后内容至行尾均为注解。

[Section1 Name]  
KeyName1=value1  
KeyName2=value2  
; 这是注解  
  
[Section2 Name]  
KeyName21=value21  
KeyName22=value22

13.4.3 Qt写ini文件

        在 Qt 中,可以使用 QSettings 类来读写 .ini 文件

#include <QApplication>  
#include <QSettings>  
  
int main(int argc, char *argv[]) {  
    QApplication a(argc, argv);  
  
    // 创建 QSettings 对象,指定 ini 文件路径和格式   
    QSettings *settings = new QSettings(  
        "hahaya.ini",         // .ini 文件名  
        QSettings::IniFormat  // 指定文件格式为 INI  
    );
  
    // 写入键值对到 ini 文件  
    settings->setValue("/ip/first", "192.168.0.1");  
    settings->setValue("ip/second", "127.0.0.1");  
    settings->setValue("port/open", "2222");  
  
    // 删除 QSettings 对象  
    delete settings;  
  
    return a.exec();  
}

13.4.4 Qt读ini文件

        在 Qt 框架中,我们利用 QSettings 类来读取 .ini 配置文件

#include <QApplication>  
#include <QSettings>  
#include <QDebug>  
  
int main(int argc, char *argv[]) {  
    QApplication a(argc, argv);  
  
    // 创建 QSettings 对象以读取 ini 文件  
    QSettings *settings = new QSettings("hahaya.ini", QSettings::IniFormat);  
  
    // 从 ini 文件中读取数据并转换为 QString  
    QString ipResult = settings->value("/ip/second").toString();  
    QString portResult = settings->value("/port/open").toString();  
  
    // 输出读取的数据  
    qDebug() << ipResult;  
    qDebug() << portResult;  
  
    // 读取完成后删除 QSettings 对象  
    delete settings;  
  
    return a.exec();  
}

13.4.5 QT读写ini文件

void saveSettings() {  
    // 开始设置组"MyAppSettings"  
    settings->beginGroup("MyAppSettings");  
  
    // 设置用户名和密码  
    settings->setValue("username", "exampleUser");  
    settings->setValue("password", "examplePassword");  
  
    // 结束设置组  
    settings->endGroup();  
  
    // 同步设置到持久存储  
    settings->sync();  
  
    // 输出保存并同步成功的消息  
    qDebug() << "Settings saved and synced.";  
}  
  
void loadSettings() {  
    // 开始读取组"MyAppSettings"  
    settings->beginGroup("MyAppSettings");  
  
    // 读取用户名和密码  
    QString username = settings->value("username").toString();  
    QString password = settings->value("password").toString();  
  
    // 结束读取组  
    settings->endGroup();  
  
    // 输出加载的设置信息  
    qDebug() << "Loaded settings:" << "Username:" << username << "Password:" << password;  
}

 

13.5 Qt对 Json 文件读写

13.5.1 Json文件介绍

        JSON(JavaScript Object Notation)是一种轻量级、语言无关的数据交换格式,用于存储和表示数据。它具有简洁清晰的层次结构,易于阅读和编写,同时也方便机器解析和生成,提高了网络传输效率。

        JSON主要处理两方面任务:数据序列化用于网络传输,以及写磁盘文件实现数据持久化存储(文件后缀通常为.json)。

        JSON包含两种基本数据格式:JSON数组JSON对象

        JSON数组:使用[ ]表示,内部元素用逗号分隔,支持多种数据类型混合,包括整形、浮点、字符串、布尔类型、JSON数组、JSON对象和空值null。

// 整形数组  
[1, 2, 3, 4, 5]  

// 混合类型数组  
[12, 13.34, true, false, "hello, world", null]  

// 数组嵌套  
[  
    ["cat", "dog", "panda"],  
    ["北京", "上海", "天津"],  
    ["luffy", "boy", 19]  
]  

// 数组和对象嵌套  
[  
    {  
        "luffy": {  
            "age": 19,  
            "father": "Monkey·D·Dragon"  
        }  
    }  
]

        JSON对象:使用{}表示,内部键值对用逗号分隔,键必须是字符串且唯一,值可以是多种数据类型。

{  
    "Name": "Ace",  
    "Sex": "man",  
    "Age": 20,  
    "Family": {  
        "Father": "Gol·D·Roger",  
        "Mother": "Portgas·D·Rouge",  
        "Brother": ["Sabo", "Monkey D. Luffy"]  
    },  
    "IsAlive": false,  
    "Comment": "yyds"  
}

        一个JSON文件只能有一个根节点(JSON对象或JSON数组),不允许有多个并列根节点。

/*正确示例,单个根节点*/
{  
    "userInfo": {  
        "name": "luffy",  
        "age": 19  
    },  
    "account": {  
        "user": "ace",  
        "passwd": "123456"  
    }  
}

13.5.2 Json在Qt中的使用

        从Qt 5.0起,Qt支持JSON,提供了四个主要类用于数据组织和解析。

Json类介绍
QJsonDocument封装JSON文档,支持UTF-8和Qt二进制格式的读写。
QJsonArray值列表,可插入和删除
QJsonObject键值对列表,键为唯一字符串,值为QJsonValue
QJsonValue封装JSON数据类型。

13.5.3 QJsonValue

        在Qt中,QJsonValue可封装六种基础数据类型:布尔、浮点(含整形)、字符串、JSON数组、JSON对象和空值。

QJsonValue jsonBool(true); // 布尔类型  
QJsonValue jsonDouble(3.14); // 浮点类型  
QJsonValue jsonString("Hello"); // 字符串类型  
// ... 其他类型的构造类似

        要判断QJsonValue内部封装的数据类型,可使用相应的判断函数:

bool isArray() const; // 判断是否为JSON数组  
bool isObject() const; // 判断是否为JSON对象  
// ... 其他判断函数类似

        在确定数据类型后,可将其转换为对应的基础数据类型:

QJsonArray toArray() const; // 转换为JSON数组  
bool toBool() const; // 转换为布尔类型  
double toDouble() const; // 转换为浮点类型  
// ... 其他转换函数类似  
QString toString() const; // 转换为字符串类型

13.5.4 QJsonObject

        QJsonObject用于封装JSON对象,可存储多个键值对,其中键为字符串,值为QJsonValue。

        以下是一些常用API函数的精简介绍及示例代码:

// 创建空的QJsonObject对象  
QJsonObject jsonObject;  
  
// 添加键值对到QJsonObject中  
jsonObject.insert("key1", QJsonValue(123)); // 添加整型值,键为"key1"  
jsonObject.insert("key2", QJsonValue("value2")); // 添加字符串值,键为"key2"  
  
// 获取QJsonObject中键值对的个数  
int count = jsonObject.size(); // 使用size()函数获取个数,count()和length()也是等效的  
  
// 通过键获取QJsonObject中的值  
QJsonValue value1 = jsonObject.value("key1"); // 使用value()函数,根据键"key1"获取值  
QJsonValue value2 = jsonObject["key2"];       // 使用operator[],根据键"key2"获取值  
  
// 删除QJsonObject中的键值对  
jsonObject.remove("key1");                       // 删除键"key1"对应的键值对  
QJsonValue takenValue = jsonObject.take("key2"); // 删除并返回键"key2"对应的值  
  
// 通过键在QJsonObject中查找  
auto it = jsonObject.find("key3"); // 查找键"key3",返回迭代器  
bool containsKey = jsonObject.contains("key4"); // 判断是否包含键"key4"  

        遍历键值对,

        1、使用迭代器

// 遍历QJsonObject中的键值对  
// 方法1:使用迭代器遍历  
for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {  
    QString key = it.key();  
    QJsonValue value = it.value();  
    // 在此处处理每个键值对  
}  

        2、使用[ ]方式(不推荐,因为需要知道所有键):

// 方法2:先获取所有键,然后遍历键列表(推荐)  
QStringList keys = jsonObject.keys(); // 获取QJsonObject中所有键的列表  
for (const QString &key : keys) {  
    QJsonValue value = jsonObject.value(key); // 根据键获取值  
    // 在此处处理每个键值对  
}  
  
// 注意:方法2中也可以使用operator[]来获取值,但推荐使用value()函数,  
// 因为如果键不存在,operator[]可能会插入一个空值,而value()则不会。

13.5.5 QJsonArray

        QJsonArray用于封装JSON数组,可存储多个QJsonValue类型的元素。

//创建空数组
QJsonArray jsonArray;

//添加数据
jsonArray.append(QJsonValue(123));           // 在尾部追加整型值  
jsonArray.insert(1, QJsonValue("inserted")); // 在索引1之前插入字符串值  
jsonArray.prepend(QJsonValue(true));         // 在数组头部添加布尔值  

// push_back和push_front与append和prepend功能相同,但命名遵循STL风格  
jsonArray.push_back(QJsonValue(456));  
jsonArray.push_front(QJsonValue(false));

//计算数组元素个数
int count = jsonArray.size(); // 使用size()函数,count()也是等效的

//从数组中取出元素
QJsonValue valueAt0 = jsonArray.at(0); // 取出索引0的元素  
QJsonValue firstValue = jsonArray.first(); // 取出头部元素  
QJsonValue lastValue = jsonArray.last(); // 取出尾部元素  
QJsonValue valueAtIndex = jsonArray[2]; // 使用operator[]取出索引2的元素

//删除数组中的元素
auto it = jsonArray.begin(); // 获取迭代器  
it++; // 移动迭代器到第二个元素  
jsonArray.erase(it); // 删除迭代器指向的元素  
  
jsonArray.pop_back(); // 删除尾部元素  
jsonArray.pop_front(); // 删除头部元素  
  
jsonArray.removeAt(1); // 删除索引1的元素  
jsonArray.removeFirst(); // 删除头部元素  
jsonArray.removeLast(); // 删除尾部元素  
  
QJsonValue takenValue = jsonArray.takeAt(0); // 删除索引0的元素并返回其值

QJ遍历数组:

        使用迭代器遍历:

for (auto it = jsonArray.begin(); it != jsonArray.end(); ++it) {  
    QJsonValue value = *it;  
    // 处理每个元素  
}

        使用数组方式遍历:

for (int i = 0; i < jsonArray.size(); ++i) {  
    QJsonValue value = jsonArray.at(i);  
    // 处理每个元素  
}

13.5.6 QJsonDocument

        在Qt中,QJsonDocument类用于封装完整的JSON文档,并支持从UTF-8编码的文本表示以及Qt的二进制格式读取和写入该文档。

QJsonObject 或 QJsonArray 转换为字符串

1、创建QJsonDocument对象:

        用QJsonDocument构造函数,将QJsonObjectQJsonArray转换为QJsonDocument对象。

QJsonObject jsonObject;  
// ... 填充jsonObject数据  
QJsonDocument jsonDoc(jsonObject);  

QJsonArray jsonArray;  
// ... 填充jsonArray数据  
QJsonDocument jsonDocArray(jsonArray);

2、序列化数据:

        调用toBinaryData()toJson()方法,将QJsonDocument对象序列化为二进制格式或文本格式的JSON字符串。

QByteArray binaryData = jsonDoc.toBinaryData();  
QByteArray jsonString = jsonDoc.toJson(QJsonDocument::Indented); // 文本格式,带缩进

3、使用字符串进行数据传输或持久化:

        将得到的字符串通过网络传输或保存到磁盘文件中。

字符串 转换为 QJsonObject 或 QJsonArray

1、解析字符串为QJsonDocument对象:

        使用QJsonDocument的静态函数fromBinaryData()fromJson(),将JSON字符串解析为QJsonDocument对象

QByteArray jsonString = ... // 从网络或文件获取的JSON字符串  
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString);

2、将文档对象转换为QJsonArray或QJsonObject:

        使用isArray()isObject()方法判断QJsonDocument对象中的数据类型,然后调用array()object()方法将其转换为相应的对象。

if (jsonDoc.isObject()) {  
    QJsonObject jsonObject = jsonDoc.object();  
    // ... 处理jsonObject  
} else if (jsonDoc.isArray()) {  
    QJsonArray jsonArray = jsonDoc.array();  
    // ... 处理jsonArray  
}

3、读取数据:

        使用QJsonArray或QJsonObject提供的API读取存储在对象中的数据。

Qt中,`QFile`类是用于处理文件I/O操作的基本工具。它的全名是`QFileDevice`的一部分,提供了对文件系统的基本访问功能,包括打开、关闭、读取、写入等操作。以下是`QFile`的一些主要方法: 1. **构造函数**: - `QFile(const QString &fileName)`:默认构造函数,创建一个空的文件对象,直到设置文件名。 - `QFile(const char *fileName)`:字符指针版本的构造函数,同上。 2. **基本操作**: - `open(int flags)`:打开文件,`flags`参数可以指定各种模式,如`QIODevice::ReadOnly`(只读)、`QIODevice::WriteOnly`(只写)和`QIODevice::ReadWrite`(读写)等。 - `close()`:关闭已经打开的文件- `isOpen()`:判断文件是否已打开。 3. **读取/写入数据**: - `read(void *data, qint64 maxSize = -1)`:读取文件到内存,`data`指针指向接收数据的位置,`maxSize`表示最多读取多少字节。 - `write(const void *data, qint64 maxSize = -1)`:将数据写入文件。 4. **文件属性**: - `size()`:获取文件大小(字节)。 - `exists()`:检查文件是否存在。 - `remove()`:删除文件。 5. **错误处理**: - `errorString()`:返回最近发生的错误信息。 - `setPermissions(qt_stat::Permissions permissions)`:设置文件权限。 示例: ```cpp QFile file("example.txt"); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Failed to open file: " << file.errorString(); } else { QByteArray content; file.read(&content); // 处理内容... file.close(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大象荒野

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值