收获10:
众所周知,在编程的时候也少不了接触二进制文件,最近就用上了这么个需求,记录一下,就不详细说明了,过程在构造函数内,代码如下:
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <complex>
#include <QFile>
#include <QTextCodec>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
#define Write
//#define Read
#ifdef Write
// 将复数保存为二进制文件
std::vector<std::complex<float>>vecOutData;
std::complex<float>cmp1(1, 3.1415);
vecOutData.push_back(cmp1);
std::complex<float>cmp2(3.1415, 1);
vecOutData.push_back(cmp2);
// 测试路径
QString strSaveFilePath("./TestFile.bin");
// 以二进制打开文件
FILE *file = fopen(strSaveFilePath.toUtf8().data(), "wb");
if (file == NULL) {
fprintf(stderr, "无法打开文件 %s 以写入。\n", strSaveFilePath.toUtf8().data());
return;
}
// 写入偏移量 假设存入数据为有多少个元素 占四个字节
int nCount = vecOutData.size();
fwrite(&nCount, sizeof(int), 1, file);
// 写入文件
for(const auto&complexValue : vecOutData)
{
float fReal = complexValue.real();
float fImag = complexValue.imag();
fwrite(&fReal, sizeof(float), 1, file);
fwrite(&fImag, sizeof(float), 1, file);
}
// 关闭文件
fclose(file);
#endif
#ifdef Read
// 将读取出的复数
std::vector<std::complex<float>>vecInData;
// 测试路径
QString strOpenFilePath("./TestFile.bin");
// 读取文件
char* pFileBuffer = nullptr;
std::vector<float> tmpSource;
// 中文路径
QTextCodec* pCode = QTextCodec::codecForName("gb2312");
QString strTemp = QString::fromLocal8Bit(pCode->fromUnicode(strOpenFilePath).data());
QFile fileRead(strTemp.toUtf8().data());
// 文件的大小(字节数)
int iFileSize = fileRead.size();
if(fileRead.open(QIODevice::ReadOnly))
{
// 读取到后赋值给 pFileBuffer
if(iFileSize > 0)
{
pFileBuffer = new char[iFileSize];
memset(pFileBuffer, 0, iFileSize);
fileRead.read(pFileBuffer, iFileSize);
}
}
// 关闭文件
fileRead.close();
if(nullptr == pFileBuffer)
return;
// 获取头的4个自己的元素个数
int* pCount = (int*)&pFileBuffer[0];
qDebug()<<"data count = "<<*pCount;
// 偏移量 为上述的存的元素个数 则便宜4个字节
int nOffset = sizeof(int);
char* pData = &pFileBuffer[nOffset];
// 假定为上述的float
int nType = 2;
switch (nType) {
case 0: // short Data
{
// 强转为short
short* pPoint = (short*)pData;
// 读取数据 因为一个复数占2个short的字节 所以要*2
int iFloats = iFileSize / (2 * sizeof(short));
for (int i = 0; i < iFloats; i++)
{
short sReal = *pPoint;
// 指针移动到下一个short
pPoint++;
short sImag = *pPoint;
// 指针移动到下一个short
pPoint++;
std::complex<float>cmp(sReal, sImag);
vecInData.push_back(cmp);
}
}
break;
case 1:// int Data
{
int* pPoint = (int*)pData;
// 读取数据 因为一个复数占2个int的字节 所以要*2
int iFloats = iFileSize / (2 * sizeof(int));
for (int i = 0; i < iFloats; i++)
{
int nReal = *pPoint;
// 指针移动到下一个short
pPoint++;
int nImag = *pPoint;
// 指针移动到下一个short
pPoint++;
std::complex<float>cmp(nReal, nImag);
vecInData.push_back(cmp);
}
}
break;
case 2:// float Data
{
float* pPoint = (float*)pData;
// 读取数据 因为一个复数占2个float的字节 所以要*2
int iFloats = iFileSize / (2 * sizeof(float));
for (int i = 0; i < iFloats; i++)
{
float fReal = *pPoint;
// 指针移动到下一个short
pPoint++;
float fImag = *pPoint;
// 指针移动到下一个short
pPoint++;
std::complex<float>cmp(fReal, fImag);
vecInData.push_back(cmp);
}
}
break;
case 3:// double Data
{
double* pPoint = (double*)pData;
// 读取数据 因为一个复数占2个double的字节 所以要*2
int iFloats = iFileSize / (2 * sizeof(double));
for (int i = 0; i < iFloats; i++)
{
double dbReal = *pPoint;
// 指针移动到下一个short
pPoint++;
double dbImag = *pPoint;
// 指针移动到下一个short
pPoint++;
std::complex<float>cmp(dbReal, dbImag);
vecInData.push_back(cmp);
}
}
break;
default:
break;
}// ending switch
// 清理内存
delete[] pFileBuffer;
pFileBuffer = nullptr;
// 测试打印数据
for(int i = 0; i < vecInData.size(); ++i)
{
qDebug() << "data" << i << " real = " << vecInData[i].real()
<< " imag = " << vecInData[i].imag();
}
#endif
}
MainWindow::~MainWindow()
{
delete ui;
}
使用FILE来按照数据的格式写入文件,读取的时候使用QFile获取数据,按照字节来读...大概是这样~
仅供参考,如有异议,以你为准~