Qt/C++使用小记10【使用Qt按照字节存储/读取二进制文件】

收获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获取数据,按照字节来读...大概是这样~

仅供参考,如有异议,以你为准~ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值