当前位置: 首页 > article >正文

Qt文件系统-文本文件读写

实例功能概述

文本文件是指以以纯文本格式存储的文件,例如用 Qt Creator 编写的 C++ 程序的头文件和源文件。HTML 和 XML 文件也是纯文本文件,只是读取之后需要对内容进行解析之后再显示。

Qt 提供了两种读写纯文本文件的基本方法,一种是用 QFile类的 QIODevice读写功能直接进行读写,另一种是利用 QFileQTextStream结合起来,用流(Stream)的方法进行文件读写。

我编写了一个例子来展示这两种方法读写文本文件的效果,现在运行结果:

QFile 读写文本

文件读取

QFile 类是直接和 IO 设备打交道的,进行文件读写操作的类,使用 QFile 可以直接打开或保存文本文件。图中“QFile 直接打开“按钮用 QFile 类的功能直接打开文本文件,按钮的槽函数及相关函数代码如下:

void MainWindow::on_actOpen_IODevice_triggered()
{//打开文件

    QString curPath=QDir::currentPath();//获取系统当前目录
    QString dlgTitle="打开一个文件"; //对话框标题
    QString filter="程序文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)"; //文件过滤器
    QString aFileName=QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter);

    if (aFileName.isEmpty())
        return;

    openTextByIODevice(aFileName);
}
bool MainWindow::openTextByIODevice(const QString &aFileName)
{//用IODevice方式打开文本文件
    QFile   aFile(aFileName);
//    aFile.setFileName(aFileName);

    if (!aFile.exists()) //文件不存在
        return false;

    if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return false;

    ui->textEditDevice->setPlainText(aFile.readAll());
    aFile.close();

    ui->tabWidget->setCurrentIndex(0);
    return  true;
}

自定义函数 openTextByIODevice()实现文本打开功能。定义了 QFile 对象变量 aFile 时将文件名传递给他,检查文件存在后,通过 open()函数打开文件;注意,QFile::open()函数打开文件时需要传递 QIODevice::OpenModeFlag枚举类型的参数,决定文件以什么方式打开,主要有以下取值:

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

文件写入

“QFile”另存为按钮用 QFile 类的功能将 QPlaintextEdit 组件中的文本保存为一个文本文件,实现代码如下:

void MainWindow::on_actSave_IODevice_triggered()
{
    QString curPath=QDir::currentPath();//获取系统当前目录
    QString dlgTitle="另存为一个文件"; //对话框标题
    QString filter="h文件(*.h);;c++文件(*.cpp);;文本文件(*.txt);;所有文件(*.*)"; //文件过滤器
    QString aFileName=QFileDialog::getSaveFileName(this,dlgTitle,curPath,filter);

    if (aFileName.isEmpty())
        return;

    saveTextByIODevice(aFileName);
}
bool MainWindow::saveTextByIODevice(const QString &aFileName)
{ //用IODevice方式保存文本文件
    QFile   aFile(aFileName);
//    aFile.setFileName(aFileName);

    if (!aFile.open(QIODevice::WriteOnly | QIODevice::Text))
        return false;

    QString str=ui->textEditDevice->toPlainText();//整个内容作为字符串

    QByteArray  strBytes=str.toUtf8();//转换为字节数组
//    QByteArray  strBytes=str.toLocal8Bit();

    aFile.write(strBytes,strBytes.length());  //写入文件

    aFile.close();
    ui->tabWidget->setCurrentIndex(0);
    return  true;
}

自定义函数 saveTextByIODevice()实现文件保存功能,为了保存文件,用 open() 打开文件时,使用的模式是 QIODevice::WriteOnly | QIODevice::Text。使用 WriteOnly 隐含着 Truncate,即删除文件原有内容。

首先将 QPlaintextEdit 组件上的文本导出为字符串,将 QString 类的 toUtf8()函数转化为 UTF8 编码的字节数组,然后调用 QFile::write()函数将字节数组内容写入文件。

QFile 和 QTextStream 结合读写文本文件

QTextStream 与 IO 读写设备结合,为数据读写提供了一些方便的方法类,QTextStream 可以与 QFile、QTemporaryFile、QBuffer、QTcpSocket 和 QUdpSocket 等 IO 设备类结合使用。

这里我们将 QFile 和 QTextStream 结合,读取文本文件的自定义函数 openTextByStream()的代码如下:

bool MainWindow::openTextByStream(const QString &aFileName)
{ //用 QTextStream打开文本文件
    QFile   aFile(aFileName);

    if (!aFile.exists()) //文件不存在
        return false;

    if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return false;

    QTextStream aStream(&aFile); //用文本流读取文件
//    aStream.setAutoDetectUnicode(true); //自动检测Unicode,才能正常显示文档内的汉字

    ui->textEditStream->setPlainText(aStream.readAll());

    aFile.close();//关闭文件
    ui->tabWidget->setCurrentIndex(1);
    return  true;
}

在创建 QTextStream 实例时传递一个 QFile 参数,这样,QFile 对象和 QTextStream 对象就结合在一起了,利用 QTextStream 可读写文件。如果文本文件里有汉字,需要设定为自动识别 Unicode 码,即调用 setAutoDetectUnicode(true)函数。

上面的代码中使用了 QTextStream::readAll()来一次性读取所有内容。但是 QTextStream提供了一些其他方便使用的接口函数,如使用 QTextStream::readLine()可以逐行读取文本,这种方式适合用于需要逐行解析字符串内容的使用场景:

bool MainWindow::openTextByStream(const QString &aFileName)
{ //用 QTextStream打开文本文件
    QFile   aFile(aFileName);

    if (!aFile.exists()) //文件不存在
        return false;

    if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return false;

    QTextStream aStream(&aFile); //用文本流读取文件
//    aStream.setAutoDetectUnicode(true); //自动检测Unicode,才能正常显示文档内的汉字

   ui->textEditStream->clear();//清空
   while (!aStream.atEnd())
   {
       str=aStream.readLine();//读取文件的一行
       ui->textEditStream->appendPlainText(str); //添加到文本框显示
   }

    aFile.close();//关闭文件
    ui->tabWidget->setCurrentIndex(1);
    return  true;
}

saveTextByStream()使用 QTextStream 保存文件的自定义函数,代码如下:

bool MainWindow::saveTextByStream(const QString &aFileName)
{//用QTextStream保存文本文件
    QFile   aFile(aFileName);

    if (!aFile.open(QIODevice::WriteOnly | QIODevice::Text))
        return false;

    QTextStream aStream(&aFile); //用文本流读取文件
//    aStream.setAutoDetectUnicode(true); //自动检测Unicode,才能正常显示文档内的汉字

    QString str=ui->textEditStream->toPlainText(); //转换为字符串

    aStream<<str; //写入文本流
    aFile.close();//关闭文件

    return  true;

}

解决中文乱码问题

在使用 QTextStream 读写有中文内容的文本文件时,为了能正确识别 Unicode 码,需要调用 setAutoDetectUnicode(true),设置 QTextStream 可以自动识别 Unicode 码,如果不做次设置,读取文件中的中文将是乱码,无法正常显示。

为了解决 Unicode 的识别问题,可以在应用程序中作全局设置,使应用程序支持 Unicode。方法是在 main 函数中使用 QTextCodec 类进行编码设置。例如:

int main(int argc, char *argv[])
{
//解决汉字乱码问题
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(codec); //解决汉字乱码问题

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

这样应用程序就有了对 Unicode 码的支持,即使在使用 QTextStream 时没有设置识别 Unicode 码,也可以显示汉字。

参考资料:https://it.0voice.com


http://www.kler.cn/a/393570.html

相关文章:

  • 如何在python中模拟重载初始化函数?
  • 探索Python的HTTP利器:Requests库的神秘面纱
  • apache2配置多站点
  • 学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
  • Vector Optimization – Stride
  • 前端-同源与跨域
  • 蓝桥杯每日真题 - 第8天
  • [CKS] K8S ServiceAccount Set Up
  • UDP协议和TCP协议之间有什么具体区别?
  • Flink+Kafka中Source和Sink的使用
  • ONLYOFFICE8.2版本测评,团队协作的办公软件
  • 新160个crackme - 096-xtFusion-k1
  • 免费送源码:Java+springboot+MySQL 物流车辆管理系统的设计与实现 计算机毕业设计原创定制
  • kafka可视化管理平台-kafka-console-ui
  • vue el-date-picker 日期选择器禁用失效问题
  • 蓝队基础(详见B站泷羽sec)
  • 计算机网络之表示层
  • 【ReactPress】React + antd + NestJS + NextJS + MySQL 的简洁兼时尚的博客网站
  • FFmpeg 怎么裁剪m4a的音频,从一个时间点开始,裁剪15秒钟的视频
  • 如何在 IntelliJ IDEA 中去掉 Java 方法注释后的空行
  • CUDA error: device-side assert triggered 报错解决
  • androidstudio下载gradle慢
  • openai Realtime API (实时语音)
  • 鸿蒙版APP-图书购物商城案例
  • 2023年MathorCup数学建模A题量子计算机在信用评分卡组合优化中的应用解题全过程文档加程序
  • ip addr show