当前位置:   article > 正文

Qt5学习笔记之bin文件合成工具二:bin文件的读取和写入_qt bin文件合并

qt bin文件合并

概述

上一小节主要是练习下本地文件的打开和另存为,现在我们开始正式bin文件合成工具的开发。

先学习《Qt学习之路2.pdf》第36节 二进制文件读写。

本篇文章的目标:
1.重新设计界面
2.实现不同bin文件的选取
3.合成bin文件涉及的内容略多:将选好的3个bin文件根据偏移量合成为1个bin文件,空出的内容填充为FF。在本篇文章,我们先实现一个bin文件的读取和另存写入。

实现步骤

1.调整界面并布局。

工具是为了自己开发方便,不求做成一个通用工具去发布给大家使用(这个可能比较耗精力,作为初学者我还是先简单实现即可)。我的实际应用中合成主要分为3端,IAP、APP、最后的参数页。界面设计如下,其中路径和偏移量的显示框我们都是用LineEdit组件,避免出现换行问题:
在这里插入图片描述

2.显示文件路径和偏移量

IAP、APP、Para三个按钮实现功能相同,选取本地bin文件,将路径和默认偏移量填写到界面的对应位置即可。在上一小节已经测试过通过文件框选取本地文件。

    QString path = QFileDialog::getOpenFileName(this,
        tr("Open File"),//控件的objectName
         ".",           //对话框显示时默认打开的目录,"." 代表程序运行目录
        tr("Bin Files(*.bin)"));   //对话框的后缀名过滤器,将txt文件改为bin文件。
    qDebug("path = %s",qPrintable(path));
  • 1
  • 2
  • 3
  • 4
  • 5

这里我们只需将过滤器修改为*.bin即可。将path打印出来,即为选中文件的绝对路径:
在这里插入图片描述
将path直接填充到路径显示框中即可。程序中没有使用path,而是使用一个QString变量获取文件信息,最后进行填充:

	QString buf;
	QFileInfo info(file);

	buf = QString(info.absolutePath());
	buf.append("/");
	buf.append(info.baseName());    //直接获得文件名
	buf.append(".bin");
	qDebug("%s",qPrintable(buf));   //与上面的path变量相同,可直接使用path变量
	qDebug() << info.filePath();

	ui->iappathEdit->setText(buf);
	ui->iapoffsizeEdit->setText(tr("0x00000000"));  //默认偏移量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.bin文件读取

要主要分为两步:根据路径显示框来获取文件、读取bin文件到程序中。

        QFile readfile(ui->iappathEdit->text());    //要读取的bin文件
        QFileInfo read_file_info(readfile);         //要读取的bin文件的信息
        if (!readfile.open(QIODevice::ReadOnly)) {  //只读方式打开bin文件
            QMessageBox::warning(this, tr("Read File"),
                tr("Cannot open file:\n%1").arg(ui->iappathEdit->text()));
            return;
        }
        QDataStream BinFileData(&readfile);  //将刚刚创建的 file 对象的指针传递给一个QDataStream实例 BinFileData
        char *pBuff = new char[read_file_info.size()];  //要读取bin文件的大小
        BinFileData.readRawData(pBuff,static_cast<int>(read_file_info.size()));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这段代码我们看两个地方:
a. readRawData函数解释如下:
在这里插入图片描述
这里实现读取数据到pBuff数组。
b. static_cast<int>强制转换:

static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型(C++强制类型转换:static_cast)。

这里将read_file_info.size()转换为int数据。

参考文章:C++四种类型转换运算符:static_cast、dynamic_cast、const_cast和reinterpret_cast_C语言中文网

double scores = 95.5;
int n = static_cast<int>(scores);
  • 1
  • 2

4.将读取的bin文件写入到新的文件。

    QString path = QFileDialog::getSaveFileName(this,
        tr("Open File"),
        ".",
        tr("Bin Files(*.bin)"));
    if(!path.isEmpty()) {
        QFile file(path);
        if (!file.open(QIODevice::WriteOnly)) {
            QMessageBox::warning(this, tr("Write File"),
                tr("Cannot open file:\n%1").arg(path));
            return;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

首先通过上一小节使用到另存为对话框,设置我们的存储目标文件。然后直接将第3步读取到的数据写入:

        file.write(pBuff);
  • 1

5.测试运行效果:

在这里插入图片描述
左侧是我们用于测试的源bin文件,右侧是通过generate功能生成的新bin文件。可以看到只有部分数据,到00正好结束。根据以往的单片机编程,很容易想到00是一个字符串的结束符。

6.解决00结束符问题

我们打印下读取的文件长度:

qDebug() << static_cast<int>(read_file_info.size());
  • 1

控制台输出为8,那么问题应该就出在了file.write(pBuff),查看函数原型:
在这里插入图片描述
可以看出,写入长度为data字符串的长度,即遇到00结束。我们将代码修改为:

	QByteArray DataAllArray;
	DataAllArray = QByteArray(pBuff,static_cast<int>(read_file_info.size()));

	file.write(DataAllArray);
  • 1
  • 2
  • 3
  • 4

再次测试,结果如下:
在这里插入图片描述

GitHub下载

点击打开查看readbin分支。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/306795
推荐阅读
相关标签
  

闽ICP备14008679号