自己写的一个bin文件合并工具。记录一下:
平台:Qt Creator 10.0.2
QT版本:Qt 6.2.4 (MinGW 11.2.0 64bit)
下面是widget.cpp原码:
#include<QRegularExpressionValidator>
#include "widget.h"
#include "ui_widget.h"
BinFileInfo bin_file_info[2];
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
QFont plaTxt_font("Arial", 20);
ui->setupUi(this);
ui->groupBox->setTitle("");//不显示groupBox名
ui->label_oprtTip->setText("**请先打开bin文件!**");
ui->label_oprtTip->setFont(QFont("Arial", 18));
ui->label_offset->setText("偏移地址0x");
ui->label_offset->setFont(QFont("Arial", 16));
ui->label_fill->setText("填充0x");
ui->label_fill->setFont(QFont("Arial", 16));
offset_addr = "00000000";
ui->plaTxtEdit_offset->setFont(plaTxt_font);
ui->plaTxtEdit_offset->setPlainText(offset_addr);
ui->plaTxtEdit_offset->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 禁用垂直滚动条
fill_data = "00";
ui->plaTxtEdit_fill->setFont(plaTxt_font);
ui->plaTxtEdit_fill->setPlainText(fill_data);
ui->plaTxtEdit_fill->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 禁用垂直滚动条
ui->label_outputName->setFont(QFont("Arial", 16));
ui->label_outputName->setText("生成文件名");
}
Widget::~Widget()
{
delete ui;
}
bool Widget::openByIO_Whole(const QString &tgtFileName, int button_num)
{
QFile *fileDevice = new QFile(tgtFileName);
uint readSize;
if (!fileDevice->exists())
return false;
if (!fileDevice->open(QIODevice::ReadOnly))
return false;
fileStream = new QDataStream(fileDevice);
fileStream->setVersion(QDataStream::Qt_6_2);
fileStream->setByteOrder(QDataStream::LittleEndian);
readSize = fileDevice->size();
if (button_num == 1)
{
if (bin_file_info[0].readData_buff != NULL)
{
free(bin_file_info[0].readData_buff);
}
bin_file_info[0].readData_buff = (char *)malloc(readSize);
bin_file_info[0].dataSize = readSize;
if (bin_file_info[0].readData_buff == NULL)
{
ui->label_oprtTip->setText("申请内存失败!");
return false;
}
fileStream->readRawData(bin_file_info[0].readData_buff, bin_file_info[0].dataSize);
}
else
{
if (bin_file_info[1].readData_buff != NULL)
{ //ram come from last malloc
free(bin_file_info[1].readData_buff);
}
bin_file_info[1].readData_buff = (char *)malloc(readSize);
bin_file_info[1].dataSize = readSize;
if (bin_file_info[1].readData_buff == NULL)
{
ui->label_oprtTip->setText("申请内存失败!");
return false;
}
fileStream->readRawData(bin_file_info[1].readData_buff, bin_file_info[1].dataSize);
}
fileDevice->close();
ui->label_oprtTip->setText("读取完成");
return true;
}
void Widget::on_phButton_openFi_clicked()
{
QString curPath = QDir::currentPath(); //获取应用程序当前目录
QString dlgTitle = "打开bin文件"; //设置对话框名称
QString fileFilter = "二进制文件(*.bin)"; //设置过滤文件类型
QString objFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, fileFilter);
if (objFileName.isEmpty())
return;
ui->plaTxtEdit_firstFile->setPlainText(objFileName);
openByIO_Whole(objFileName,1);
}
void Widget::on_phButton_openSe_clicked()
{
QString curPath = QDir::currentPath(); //获取应用程序当前目录
QString dlgTitle = "打开bin文件"; //设置对话框名称
QString fileFilter = "二进制文件(*.bin)"; //设置过滤文件类型
sndFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, fileFilter);
if (sndFileName.isEmpty())
return;
ui->plaTxtEdit_secondFile->setPlainText(sndFileName);
openByIO_Whole(sndFileName, 2);
//如果用户没有输入输出文件名,则设置默认文件名
if (output_file_name.length() == 0)
{
init_flag = 1;
output_file_name = sndFileName.sliced(0, sndFileName.length() - 4) + "_new.bin";
ui->plaTxtEdit_outputName->setPlainText(output_file_name);
init_flag = 0;
}
}
void Widget::on_plaTxtEdit_offset_textChanged()
{
offset_addr = ui->plaTxtEdit_offset->toPlainText();
//user only can input letter or number all 8 characters
QRegularExpression expre("^[A-Fa-f0-9]{1,8}$");
if (!expre.match(offset_addr).hasMatch())
{
if (offset_addr.length() > 0)
{
offset_addr = offset_addr.left(offset_addr.length() - 1);
ui->plaTxtEdit_offset->setPlainText(offset_addr);
}
else
{
offset_addr = "00000000";
}
}
}
void Widget::on_plaTxtEdit_fill_textChanged()
{
fill_data = ui->plaTxtEdit_fill->toPlainText();
//user only can input letter or number all 8 characters
QRegularExpression expre("^[A-Fa-f0-9]{1,2}$");
if (!expre.match(fill_data).hasMatch())
{
if (fill_data.length() > 0)
{
fill_data = fill_data.left(fill_data.length() - 1);
ui->plaTxtEdit_fill->setPlainText(fill_data);
}
else
{
fill_data = "00";
}
}
}
void Widget::on_phButton_joint_clicked()
{
uint writeSize, offset_addr_num;
unsigned char fill_data_hex;
char *obj_buff = NULL;
bool ok;
offset_addr_num = offset_addr.toInt(&ok, 16);
if (offset_addr_num < bin_file_info[0].dataSize)
{
ui->label_oprtTip->setText("偏移地址与第一个文件重叠!");
return;
}
writeSize = bin_file_info[1].dataSize + offset_addr_num;
obj_buff = (char *)malloc(writeSize);
if (obj_buff == NULL)
{
ui->label_oprtTip->setText("申请内存失败!");
return;
}
ui->plaTxtEdit_offset->setPlainText(offset_addr);
ui->plaTxtEdit_fill->setPlainText(fill_data);
fill_data_hex = fill_data.toInt(&ok, 16);
memset(obj_buff,fill_data_hex, writeSize);
memcpy(obj_buff, bin_file_info[0].readData_buff, bin_file_info[0].dataSize);
memcpy(obj_buff + offset_addr_num, bin_file_info[1].readData_buff, bin_file_info[1].dataSize);
QFile *FileOutput_handle = new QFile(output_file_name);
if (!FileOutput_handle->open(QIODevice::WriteOnly))
return;
fileStream = new QDataStream(FileOutput_handle);
fileStream->setVersion(QDataStream::Qt_6_2);
fileStream->setByteOrder(QDataStream::LittleEndian);
fileStream->writeRawData(obj_buff, writeSize);
FileOutput_handle->close();
delete fileStream;
delete FileOutput_handle;
free(obj_buff);
ui->label_oprtTip->setText("合并完成!");
}
void Widget::on_plaTxtEdit_outputName_textChanged()
{
QString fileType;
if (init_flag)
return;
output_file_name = ui->plaTxtEdit_outputName->toPlainText();
//user only can input letter or number all 8 characters
fileType = output_file_name.section('.', -1);
if (output_file_name == sndFileName)
{
output_file_name = sndFileName.sliced(0, sndFileName.length() - 4) + "_new.bin";
ui->plaTxtEdit_outputName->setPlainText(output_file_name);
}
else if (output_file_name.length() == 0)
{
output_file_name = sndFileName.sliced(0, sndFileName.length() - 4) + "_new.bin";
ui->plaTxtEdit_outputName->setPlainText(output_file_name);
}
else if (fileType != "bin")
{
output_file_name = sndFileName.sliced(0, sndFileName.length() - 4) + "_new.bin";
ui->plaTxtEdit_outputName->setPlainText(output_file_name);
}
}
void Widget::closeEvent(QCloseEvent *event)
{ //free ram resource when close tool
free(bin_file_info[0].readData_buff);
free(bin_file_info[1].readData_buff);
event->accept();
}
main.cpp代码如下:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.setWindowTitle("bin合并工具");
w.show();
return a.exec();
}
widget.h代码如下:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFileDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_phButton_openFi_clicked();
bool openByIO_Whole(const QString &tgtFileName, int button_num);
void on_phButton_openSe_clicked();
void on_plaTxtEdit_offset_textChanged();
void on_plaTxtEdit_fill_textChanged();
void on_phButton_joint_clicked();
void on_plaTxtEdit_outputName_textChanged();
void closeEvent(QCloseEvent *);
private:
Ui::Widget *ui;
QDataStream *fileStream;
QString offset_addr;
QString fill_data;
QString output_file_name;
QString sndFileName;
bool init_flag;
};
class BinFileInfo
{
public:
char *readData_buff;
uint dataSize;
};
#endif // WIDGET_H
widget.ui代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>437</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>761</width>
<height>401</height>
</rect>
</property>
<property name="title">
<string>GroupBox</string>
</property>
<widget class="QPlainTextEdit" name="plaTxtEdit_firstFile">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>561</width>
<height>75</height>
</rect>
</property>
</widget>
<widget class="QPlainTextEdit" name="plaTxtEdit_secondFile">
<property name="geometry">
<rect>
<x>30</x>
<y>140</y>
<width>561</width>
<height>75</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phButton_openFi">
<property name="geometry">
<rect>
<x>610</x>
<y>67</y>
<width>93</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>打开</string>
</property>
</widget>
<widget class="QPushButton" name="phButton_openSe">
<property name="geometry">
<rect>
<x>610</x>
<y>170</y>
<width>93</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>打开</string>
</property>
</widget>
<widget class="QLabel" name="label_oprtTip">
<property name="geometry">
<rect>
<x>70</x>
<y>360</y>
<width>501</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="plaTxtEdit_offset">
<property name="geometry">
<rect>
<x>160</x>
<y>300</y>
<width>181</width>
<height>41</height>
</rect>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
</widget>
<widget class="QLabel" name="label_offset">
<property name="geometry">
<rect>
<x>40</x>
<y>310</y>
<width>111</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QLabel" name="label_fill">
<property name="geometry">
<rect>
<x>350</x>
<y>308</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="plaTxtEdit_fill">
<property name="geometry">
<rect>
<x>430</x>
<y>300</y>
<width>101</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="phButton_joint">
<property name="geometry">
<rect>
<x>610</x>
<y>310</y>
<width>93</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>合并</string>
</property>
</widget>
<widget class="QLabel" name="label_outputName">
<property name="geometry">
<rect>
<x>28</x>
<y>250</y>
<width>111</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QPlainTextEdit" name="plaTxtEdit_outputName">
<property name="geometry">
<rect>
<x>150</x>
<y>230</y>
<width>441</width>
<height>41</height>
</rect>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
工具界面如下所示: