Qt读写CSV文件的几种方式及优劣

2023-10-26

前言

作为一种常见的数据交换格式,CSV(Comma Separated Values)文件常常用于数据导出和导入等场合。在实际开发中,我们也需要使用Qt来实现CSV文件的读写操作。本篇博客将介绍使用Qt实现CSV读写的方法,并分析每种实现方式的优缺点。

一、使用QStringList及QTextStream实现CSV文件读写

本方法使用QStringList来保存每行数据,使用QTextStream类读写文本文件。具体实现代码如下:

// 读取CSV文件
bool readCsv(QString filePath, QList<QStringList>& data)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return false;

    QTextStream stream(&file);
    while (!stream.atEnd())
    {
        QString line = stream.readLine();
        QStringList row = line.split(',', Qt::SkipEmptyParts);
        data.append(row);
    }

    file.close();
    return true;
}

// 写入CSV文件
bool writeCsv(QString filePath, QList<QStringList>& data)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return false;

    QTextStream stream(&file);
    for (int i = 0; i < data.size(); i++)
    {
        QStringList row = data.at(i);
        for (int j = 0; j < row.size(); j++)
        {
            stream << row.at(j);
            if (j < row.size() - 1)
                stream << ",";
        }
        stream << "\n";
    }

    file.close();
    return true;
}

该示例代码运用了QTextStream的readLine()和<<运算符来实现CSV文件数据的读写。需要注意的是,在读取CSV文件时,要使用QStringList的split()函数来将每行拆分为多个字符串,并用字符串列表保存。在写入CSV文件时,要使用QStringList的join()函数来将每行数据转为字符串,并用逗号分隔,产生一条CSV行,最后一行不应该有逗号。

优点:

  • 实现简单:使用QStringList和QTextStream实现CSV读写操作非常简单,能够快速上手;
  • 代码量少:相对其他实现方式,该方法实现的代码量较少。

缺点:

  • 写入数据顺序不能改变:当数据量大的时候,使用该方法逐行写入文件,文件I/O开销相对较大,导致写入速度变慢。同时,该实现方式要求数据顺序不能改变,因为每行数据只存储在单独的QStringList中。

二、使用QTextCodec及QByteArray实现CSV文件读写

本方法使用QTextCodec来处理编码问题,并使用QByteArray来读写文件。具体实现如下:

// 读取CSV文件
bool readCsv(QString filePath, QList<QStringList>& data)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly))
        return false;

    QTextCodec* codec = QTextCodec::codecForName("UTF-8");   // 使用UTF-8编码
    QByteArray content = file.readAll();
    QString text = codec->toUnicode(content);
    QStringList lines = text.split('\n');

    for (int i = 0; i < lines.size(); i++)
    {
        if (!lines.at(i).isEmpty())
        {
            QStringList row = lines.at(i).split(',');
            data.append(row);
        }
    }

    file.close();
    return true;
}

// 写入CSV文件
bool writeCsv(QString filePath, QList<QStringList>& data)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly))
        return false;

    QTextCodec* codec = QTextCodec::codecForName("UTF-8");   // 使用UTF-8编码

    for (int i = 0; i < data.size(); i++)
    {
        QStringList row = data.at(i);
        QString line = row.join(",");
        line += "\n";
        QByteArray encodedLine = codec->fromUnicode(line);
        file.write(encodedLine);
    }

    file.close();
    return true;
}

该示例代码在读取CSV文件时使用了QTextCodec的codecForName()方法来指定文件编码为UTF-8,使用QByteArray类保存文件数据,通过QTextCodec::toUnicode()函数将字节数组转换成QString对象。在写入CSV文件时,使用QByteArray类保存每行数据,并将数据编码成字节数组后写入文件。

优点:

  • 适用性广泛:该实现方式适用性广泛,可以处理各种不同的字符编码;
  • 写入速度快:使用QByteArray类来读写文件,文件I/O开销相对较少。

缺点:

  • 实现复杂:相对于第一种实现方式,该方法需要处理编码问题和字节流转换问题,因此实现方式相对复杂一些。

三、使用QStandardItemModel实现CSV文件读写

本方法使用QStandardItemModel来保存每行数据,并使用QTextStream来读写文件。具体实现如下:

// 读取CSV文件
bool readCsv(QString filePath, QStandardItemModel* model)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return false;

    QTextStream stream(&file);
    while (!stream.atEnd())
    {
        QString line = stream.readLine();
        QStringList row = line.split(',', Qt::SkipEmptyParts);
        QList<QStandardItem*> items;
        for (int i = 0; i < row.size(); i++)
        {
            QStandardItem* item = new QStandardItem(row.at(i));
            items.append(item);
        }
        model->appendRow(items);
    }

    file.close();
    return true;
}

// 写入CSV文件
bool writeCsv(QString filePath, QStandardItemModel* model)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return false;

    QTextStream stream(&file);
    for (int i = 0; i < model->rowCount(); i++)
    {
        QStringList row;
        for (int j = 0; j < model->columnCount(); j++)
        {
            QString cell = model->index(i, j).data().toString();
            row.append(cell);
        }
        stream << row.join(",") << "\n";
    }

    file.close();
    return true;
}

该示例代码使用了QStandardItemModel类来保存每行数据,并使用QTextStream类读写文件。在读取CSV文件时,使用QStandardItemModel的appendRow()函数向模型中添加新行,并在每行中保存对应的QStandardItem对象的指针。在写入CSV文件时,从QStandardItemModel中取出每个单元格的数据,将其转换成字符串后,保存到QStringList中,并使用QTextStream类的<<运算符将数据写入到文件中。

优点:

  • 具有更好的扩展性:相对于前两种实现方式,使用QStandardItemModel实现CSV读写操作具有更好的扩展性和灵活性;
  • 数据顺序可改变:使用QStandardItemModel保存数据可以方便地改变数据顺序,并且可以添加自定义的数据项(例如:QComboBox)。

缺点:

  • 实现相对复杂:相对于前两种实现方式,使用QStandardItemModel实现CSV读写操作需要考虑到数据处理和模型层次结构的复杂性;
  • 内存消耗较大:使用QStandardItemModel来保存每行数据,可能会导致内存消耗较大。

最后

本篇博客介绍了四种使用Qt实现CSV文件读写操作的方法,分别是:

  • 使用QStringList及QTextStream实现CSV文件读写;
  • 使用QTextCodec及QByteArray实现CSV文件读写;
  • 使用QStandardItemModel实现CSV文件读写;

每种实现方式都有自己的优缺点,在实际开发中可以根据具体应用场景选择适用的实现方法。

总的来说,对于小型数据量的CSV文件,使用QStringList及QTextStream实现CSV文件读写是一个比较好的选择,因为实现相对简单;对于大型数据量的CSV文件,使用QTextCodec及QByteArray可以更快地进行文件I/O操作;使用QStandardItemModel可以更好地处理数据添加、删除、排序等操作,但相对复杂一些。而对于使用频率较高的CSV读写操作,可以考虑使用基于Qt的CSV库或插件,这样可以更快地实现CSV文件读写操作。

当然,在实际开发中还涉及到其他问题,例如文件路径的处理、文件打开失败处理等,本文示例中并未全部涉及,可根据具体应用场景进行扩展。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt读写CSV文件的几种方式及优劣 的相关文章

随机推荐

  • CTFSHOW-sql注入

    web171 最简单的sql注入 先演示基本操作 payload 1 union select 1 2 database 得到数据库名为ctfshow web 1 union select 1 2 group concat table na
  • 我的一个基于stm32的独立按键扫描方式

    这两天完成了一个stm32的工程 在解决按键时写出了一个独立按键的扫描函数 应该有前辈已经出来了 的其实质就是普通的扫描方式修改的 优点是将按键相关参数封装为一个结构体 每加一个按键都不需要在函数中增加语句 废话少说 先看扫描函数 Func
  • 提高java反射速度的方法method.setAccessible(true)

    java代码中 常常将一个类的成员变量置为private 在类的外面获取此类的私有成员变量的value时 需要注意 测试类 public class AccessibleTest private int id private String
  • 插入排序 冒泡 选择 快速

    package test public class Demo5 3 param args public static void main String args int arr1 1 6 0 1 9 3 2 44 33 77 用插入法定义一
  • DataBinding使用笔记

    1 封装Activity Fragment Dialog 要使用泛型
  • 把前端NPM和Yarn的依赖和缓存的存储位置改到D盘

    执行 npm config set prefix D App lib node npm global npm config set cache D App lib node npm cache Path 环境变量添加D App lib no
  • maven 工程结构 和 archetype 模板

    文章目录 一 maven 工程结构 1 1 jar 工程结构 1 2 war 工程结构 二 archetype 模板 2 1 推荐的 archetype 模板 2 2 自定义 archetype 模板 2 2 1 自定义模板示例 有没有好奇
  • 网安态势感知详细介绍

    定义 态势感知 Situation Awareness SA 能够检测出超过20大类的云上安全风险 包括DDoS攻击 暴力破解 Web攻击 后门木马 僵尸主机 异常行为 漏洞攻击 命令与控制等 利用大数据分析技术 态势感知可以对攻击事件 威
  • FPGA开发流程简述

    FPGA开发流程简述 一 概述 FPGA Field Programmable Gate Array 是一种可编程逻辑器件 以其灵活性和高性能而被广泛应用于嵌入式系统和数字电路设计 在进行FPGA开发时 需要经历一系列的流程来完成设计 验证
  • HashTable原理和底层实现

    1 概述 上次讨论了HashMap的结构 原理和实现 HashSet and HashMap源码剖析 https blog csdn net qq 27574367 article details 88526194 本文来对Map家族的另外
  • BERT :Pre-training of Deep Bidirectional Transformers for Language Understanding论文阅读笔记(NAACL 2019)

    目录 原文翻译 BERT 用于语言理解的深度双向Transformer预训练 原文链接 https aclanthology org N19 1423 pdf 摘要 1 引言 2 相关工作 2 1 基于特征的方法 2 2 微调方法 2 3
  • 基于arduino的串口控制数码管(5611AH)显示数字(初学,入门级附代码)

    基于arduino的串口控制数码管 5611AH 显示数字只有干货 首先先要介绍一下数码管了 这里图片为5611AH 这种数码管主要分为共阴极和共阳极两种 这里用的是共阴极的 注意区分 话不多说 直接上图片 此图为模拟图 当然我有实物 实物
  • vs2008创建动态库和使用动态库的方法

    一 创建动态库 打开vs2008 新建一个项目 选择win32 gt 控制台应用程序 gt 输入名称 点击确定 点击下一步 选择DLL gt 勾选空项目 点击完成 至此工程创建完毕 向工程中添加 h文件 声明接口函数 声明函数前加上关键字
  • 常用几何算法

    1 矢量减法设二维矢量 P x1 y1 Q x2 y2 则矢量减法定义为 P Q x1 x2 y1 y2 显然有性质 P Q Q P 如不加说明 下面所有的点都看作矢量 两点的减法就是矢量相减 2 矢量叉积设矢量P x1 y1 Q x2 y
  • 这个高仿小米商城项目太惊艳了

    我的引语 晚上好 我是吴小龙同学 我的公众号 菜鸟翻身 会推荐 GitHub 上好玩的项目 一分钟 get 一个优秀的开源项目 挖掘开源的价值 欢迎关注我 平时总觉得还有很多事情要去做 然而当真的闲下来时却不一定去做 比如今年这个天天在家窝
  • LPMM阅读笔记

    https www cnblogs com ChipView p 9278614 html LPMM阅读笔记 第1章 引言 LPMM阅读笔记 1 写给自己 转眼间我已经工作了两年 在这两年里 为了工作需要我看了很多相关书籍 在我看书的时候都
  • Linux·软中断&tasklet

    目录 软中断 中断服务接口管理 tasklet 软中断 首先明确一个概念软中断 不是软件中断int n 总来来说软中断就是内核在启动时为每一个内核创建了一个特殊的进程 这个进程会不停的poll检查是否有软中断需要执行 如果需要执行则调用注册
  • 网络爬虫js逆向解决网站登录RSA加密问题,不使用selenium如何实现登录,session维持登录状态请求爬取

    记录中大网校破解登录后爬取的方法 案例请求地址 中大网校会员中心 登陆入口 中大网校 使用工具 打码平台 超级鹰 分析请求 分析此请求 得知没有data 保持状态登录需要服务器知道是这个用户对应请求的相应验证码 所以要用session来维护
  • Spring Boot中自定义注解

    在Spring Boot中 我们可以通过自定义注解来实现一些特定的功能 自定义注解可以让我们的代码更加简洁 易于维护 并且可以提高代码的可读性和可扩展性 本文将介绍如何在Spring Boot中自定义注解 定义注解 首先 我们需要定义一个注
  • Qt读写CSV文件的几种方式及优劣

    前言 作为一种常见的数据交换格式 CSV Comma Separated Values 文件常常用于数据导出和导入等场合 在实际开发中 我们也需要使用Qt来实现CSV文件的读写操作 本篇博客将介绍使用Qt实现CSV读写的方法 并分析每种实现