Vector BLF格式转ASC格式软件 QT+C++编写

前言

PS(2024-01-15:代码有更新,上传到github上去了,就不贴到这里了,主要增加了错误帧的解析)

在汽车行业里面,关于通信的话题绝对离不开的公司Vector,他们家的CANoe几乎是每个汽车厂家必备的设备。工程师在调试的时候,用于记录数据的BLF格式,是加密过的,需要用到CANoe才能打开,但是又不通每个人的电脑装个CANoe,毕竟这玩意要软件硬件一起搭配使用。但是Vector公司也提供了解析BLF文件格式的库,那就好办了,自己用他的库写一个转换软件就好了

以下是我自己用QT写的一个小工具。文末有下载地址

实践

开发环境:

VS2022+QT5.14,看你的吧,什么开发环境不是重点,有个界面就行

BLF解析库:下载地址。实在没有积分的,就直接去github下载工程文件吧

在VS配置好环境就行

主要部分:


void KUSBLFTOASC::runConveter()
{
    QByteArray dd = m_sBlfName.toLocal8Bit();
    LPCSTR pFileName = dd.data();
    DWORD dwWritten;
    LONG64 sta = 0;
    QFile file(m_sAscName);
   

    DWORD *pRead=new DWORD();
    *pRead = 1;
    {
        HANDLE hFile;
        VBLObjectHeaderBase base;
        VBLCANMessage message;
        VBLCANMessage2_t message2;
        VBLEnvironmentVariable variable;
        VBLEthernetFrame ethframe;
        VBLAppText appText;
        VBLFileStatisticsEx statistics = { sizeof(statistics) };
        BOOL bSuccess;

        if (NULL == pRead)
        {
            emit sigInit(-88);
            return;
        }
        
        *pRead = 0;

        /* open file */
        hFile = BLCreateFile(pFileName, GENERIC_READ);

        if (INVALID_HANDLE_VALUE == hFile)
        {
            emit sigInit(-88);
            return ;
        }

        BLGetFileStatisticsEx(hFile, &statistics);
        int n = statistics.mObjectCount / 100;
        int mn = 0;
        emit sigInit(n);
        emit sigStatus(0);
        bSuccess = TRUE;

        bool isok = file.open(QIODevice::WriteOnly);
        if (!isok)
        {
            emit sigInit(-88);
            return;
        }
        QTextStream filestream(&file);
        QString data = "date " + Mon.at(statistics.mMeasurementStartTime.wMonth) + " "
            + Week.at(statistics.mMeasurementStartTime.wDayOfWeek)
            + " " + QString::number(statistics.mMeasurementStartTime.wDay)
            + " " + QString::number(statistics.mMeasurementStartTime.wHour)
            + ":" + QString::number(statistics.mMeasurementStartTime.wMinute)
            + ":" + QString::number(statistics.mMeasurementStartTime.wSecond)
            + "." + QString::number(statistics.mMeasurementStartTime.wMilliseconds) + "\nbase hex  timestamps absolute\ninternal events logged\n// version N/A\n";

        filestream << data;
        /* read base object header from file */
        while (RunState&&bSuccess && BLPeekObject(hFile, &base))
        {
            switch (base.mObjectType)
            {
            case BL_OBJ_TYPE_CAN_MESSAGE:
                /* read CAN message */
                message2.mHeader.mBase = base;
                bSuccess = BLReadObjectSecure(hFile, &message2.mHeader.mBase, sizeof(message2));
                /* free memory for the CAN message */
                if (bSuccess) {
                    QString id = QString::number(message2.mID - 0x7FFFFFFF, 16);
                   
                    QString dir = CAN_MSG_DIR(message2.mFlags) == 0 ? "\tRx" : "\tTx";
                    
                    QString str = QString("%1 %2  %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15")
                        .arg(QString::number(message2.mHeader.mObjectTimeStamp/1000000000.0,'f',6))
                        .arg(QString::number(message2.mChannel))
                        .arg("0x" + QString::number((message2.mID - 0x7FFFFFFF)-1, 16).toUpper())
                        .arg(dir)
                        .arg("d")
                        .arg(QString::number(message2.mDLC))
                        .arg(QString::number(message2.mData[0],16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[1], 16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[2], 16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[3], 16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[4], 16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[5], 16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[6], 16).toUpper(), 2, QLatin1Char('0'))
                        .arg(QString::number(message2.mData[7], 16).toUpper(), 2, QLatin1Char('0'))
                        /*.arg("Length = "+QString::number(message2.mFrameLength))
                        .arg("BitCount = "+QString::number(message2.mBitCount))*/
                        .arg("ID = "+QString::number(message2.mID - 0x7FFFFFFF-1)+"x") + "\n";
                    if (isFilter)
                    {
                        if (fifter.size() > 0)
                        {
                            for (int i = 0; i < fifter.size(); i++)
                            {
                                if (id.toUpper() == fifter.at(i).toUpper())
                                {
                                    filestream << str;
                                }
                            }
                        }
                    }
                    else
                    {
                        filestream << str;
                    }
                   
                        BLFreeObject(hFile, &message2.mHeader.mBase);
                }
                break;
            case BL_OBJ_TYPE_ENV_INTEGER:
            case BL_OBJ_TYPE_ENV_DOUBLE:
            case BL_OBJ_TYPE_ENV_STRING:
            case BL_OBJ_TYPE_ENV_DATA:
                /* read environment variable */
                variable.mHeader.mBase = base;
                bSuccess = BLReadObjectSecure(hFile, &variable.mHeader.mBase, sizeof(variable));
                /* free memory for the environment variable */
                if (bSuccess) {
                    BLFreeObject(hFile, &variable.mHeader.mBase);
                }
                break;
            case BL_OBJ_TYPE_ETHERNET_FRAME:
                /* read ethernet frame */
                ethframe.mHeader.mBase = base;
                bSuccess = BLReadObjectSecure(hFile, &ethframe.mHeader.mBase, sizeof(ethframe));
                /* free memory for the frame */
                if (bSuccess) {
                    BLFreeObject(hFile, &ethframe.mHeader.mBase);
                }
                break;
            case BL_OBJ_TYPE_APP_TEXT:
                /* read text */
                appText.mHeader.mBase = base;
                bSuccess = BLReadObjectSecure(hFile, &appText.mHeader.mBase, sizeof(appText));
                if (NULL != appText.mText)
                {
                    printf("%s\n", appText.mText);
                }
                /* free memory for the text */
                if (bSuccess) {
                    BLFreeObject(hFile, &appText.mHeader.mBase);
                }
                break;
            default:
                /* skip all other objects */
                bSuccess = BLSkipObject(hFile, &base);
                break;
            }

            if (bSuccess)
            {
                *pRead += 1;
            }
            ++sta;
            if(sta%100==0 || (sta/100)>= n)
                emit sigStatus(++mn);
            if (!RunState)
            {
                filestream.flush();
                file.close();
                return;
            }
        }
        filestream.flush();
        file.close();
        emit sigStatus(n);
        emit sigInit(-99);
        /* close file */
        if (!BLCloseHandle(hFile))
        {
            return ;
        }

 
    }
}

代码没几行,自己看应该能看懂

附上Github工程地址:GitHub - BiggerBinBin/KUS-BLFTOASC: blf文件转asc文件格式

或者直接程序(CSDN)下载使用:点我下载

github运行文件下载:点我下载

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: CSV文件(Comma-Separated Values)是一种以逗号作为字段分隔符的文本文件格式,用于存储表格数据。而BLF文件(Binary Log File)是一种二进制格式的日志文件,通常用于记录某个系统或应用程序的运行过程中的事件和数据。 通常情况下,CSV文件是不直接可以换成BLF格式文件的,因为它们是完全不同的文件格式。CSV文件只存储数据值,而BLF文件存储着更加复杂的结构化数据和相关的信息。 要将CSV文件BLF格式文件,通常需要进行以下步骤: 1. 读取CSV文件的数据:使用适当的编程语言或工具,读取CSV文件中的数据并以合适的数据结构进行保存。 2. 创建BLF文件的结构:BLF文件通常有特定的结构,包括头部信息、记录类型以及每个记录的格式等。根据需要,创建一个与CSV数据相对应的BLF文件结构。 3. 将CSV数据映射到BLF文件:根据BLF文件结构中的记录类型和格式要求,将CSV数据映射到相应的字段和数据类型中。 4. 将数据写入BLF文件:将映射后的数据写入BLF文件,确保符合BLF文件的规范和格式要求。 需要注意的是,这个过程中需要根据具体的数据结构和编程语言选择合适的技术和工具。另外,一些特殊的CSV文件可能无法直接换成BLF文件,需要额外的数据处理和换步骤。 总之,CSV文件可以通过一定的数据处理和换步骤BLF格式文件,但具体的换方法和工具需要根据实际需求和情况来确定。 ### 回答2: CSV文件是以逗号分隔的文本文件,常用于存储表格数据。而BLF文件是一种二进制文件,通常用于存储音频文件或者日志文件。因为两种文件格式和存储方式不同,所以不能直接将CSV文件换为BLF格式文件换CSV文件BLF文件,需要经过以下步骤: 1. 首先,将CSV文件的数据提取出来。可以使用编程语言如Python或者专门的数据处理软件来操作,将CSV文件中的数据按照需要的格式进行处理,提取出来。 2. 然后,根据BLF文件格式要求,将提取出来的数据进行整理和换。BLF文件有特定的数据结构和编码规则,按照BLF格式的要求重新组织数据。 3. 最后,将整理好的数据按照BLF文件格式写入二进制文件。可以使用编程语言中的文件操作相关函数或者专门的文件换工具来完成。 总之,将CSV文件换为BLF格式文件需要进行数据的提取、整理和编码换等多个步骤。这是一个相对复杂的过程,需要根据具体的应用场景和数据格式要求进行定制开发或使用专门的工具来实现。 ### 回答3: CSV文件BLF文件是两种不同的文件格式,不能直接将CSV换为BLF格式。 CSV是一种常见的文本文件格式,它以逗号分隔不同的数据字段,并且每一行表示一个数据记录。CSV文件通常用于存储和交换表格数据。 而BLF(Binary log format)是一种二进制日志文件格式,它通常用于存储系统或应用程序的日志记录。BLF文件包含了时间戳、事件类型、数据包等信息,用于跟踪和分析系统行为。 由于CSV和BLF文件的结构和存储方式不同,所以无法直接换。如果需要将CSV文件的数据换为BLF文件,需要借助专门的文件换工具或编程语言来实现数据的重组和换。具体的换过程将取决于CSV文件的结构和需要生成的BLF文件的要求。 总结来说,CSV不能直接换成BLF格式文件,需要借助额外的工具或编程手段实现数据的换和重组。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值