当前位置:网站首页>C # Hex file transfer skills necessary article 】 【 bin file code implementation

C # Hex file transfer skills necessary article 】 【 bin file code implementation

2022-08-10 21:45:00 bright as noon


引言

在了解hexIt is better to read this article on the basis of file format.Read the article below:

【HEX文件格式详解】https://star-302.blog.csdn.net/article/details/119563635

一、需求

将hexThe contents of the file are converted into address order(从低到高)Arranged binary data(bin文件)

二、Ideas for writing code

The whole process is mainly divided into three steps:

  1. 遍历整个hex文件,Find the minimum and maximum addresses(That is, the start address and end address),Calculate the data length(数据长度=结束地址-起始地址+1),According to the obtained data length,Allocate memory of the corresponding size(开辟一个数组);

  2. Iterate over the whole againhex文件,Calculate the starting address AND in each data recordhex文件起始地址的偏移量,Write the data part of this data record into the array of the first step according to the offset.(In this way, the entire address is arranged in order from low to highhex文件的数据).

  3. Finally, just write the array out to a file.

三、代码实现【C#】

在这里插入图片描述

using System;
using System.Globalization;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    
    /* 说明: 1.hexExample of content reading rules: OxO-Ox500【All byte contents are there】 0x0-0x100,0x300-Ox500 【Some addresses are missing in the middle,Filled by default according to the actual situationOx00/OxFF】 2.The extended address partition can also be flashed【重点!!!】:hexIf the file address is partitioned(segment),This code can also pass */
    public partial class Form1 : Form
    {
         
        public Form1()
        {
    
            InitializeComponent();
        }
        public static string hexFilePath = null;//选择的hex文件路径
        public static string binFilePath = null;//保存的bin文件路径

        private void btn_OpenFile_Click(object sender, EventArgs e)
        {
    
            OpenFileDialog open = new OpenFileDialog();
            open.RestoreDirectory = true;
            //open.Filter = "File(*.hex,*.s19)|*.hex;*.s19|BIN File(*.bin)|*.bin";
            open.Filter = "File(*.hex)|*.hex";

            open.InitialDirectory = Directory.GetCurrentDirectory();
            if (DialogResult.OK == open.ShowDialog())
            {
    
                hexFilePath = txt_HexFile.Text = open.FileName;
                binFilePath = open.FileName.Replace(".hex", ".bin");//确定生成的bin文件路径
            }
        }

        private void btn_StartConvert_Click(object sender, EventArgs e)
        {
    
            try
            {
    
                //【01】获取hexThe starting and ending addresses of the file(Lowest_Address和Highest_Address) ,and get its length in bytes(dataLength)
                GetAddress(hexFilePath);
                byte[] buffer = new byte[dataLength]; //创建和hexA byte array of the corresponding length of the file

                //【02】填充数组内容
                //(情形1:All address content is therehex文件中;情形2:在hexSome addresses in the file are missing,Default values ​​need to be populated“0x00”或“0xFF”)
                FillData(hexFilePath, ref buffer);
                //【03】Write the array tobin文件
                WritetoBinFile(binFilePath, buffer, 0, dataLength);
                MessageBox.Show("转换成功");
            }

            catch (Exception ex)
            {
    
                MessageBox.Show(ex.Message);
            }

        }

        public static int startAddress = 0;//The starting address of the parsing
        public static int endAddress = 0;//The resolved termination address
        public static int dataLength = 0;//字节总长度=endAddress-startAddress+1

        public static string startExtendedAddress = "0000";//The first extension address
        public static string endExtendedAddress = "0000";//The last extension address
        public static bool isFirstExtendedAddress = true;//Is it detected for the first time“0x04”

        public static string startDataAddress = "0000";//The first data address【对应startExtendedAddress】
        public static string endDataAddress = "0000";//The last data address【对应endExtendedAddress】
        public static bool isFirstDataAddress = true;//Is it detected for the first time“0x00”

        public static string lastDataLength = "00";//The data length of the last line

        /// <summary>
        /// 【第1步】获取hexThe starting and ending addresses of the file,and get its length in bytes
        /// </summary>
        /// <param name="hexPath"></param>
        private void GetAddress(string hexPath)
        {
    
            FileStream fsRead = new FileStream(hexPath, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader HexReader = new StreamReader(fsRead); //读取数据流

            while (true)
            {
    
                string currentLineData = HexReader.ReadLine(); //读取Hex中一行
                if (currentLineData == null) {
     break; } //读取完毕,退出
                if (currentLineData.Substring(0, 1) == ":") //Determine the first character is”:”
                {
    
                    if (currentLineData.Substring(1, 8) == "00000001")
                    {
    
                        if (endExtendedAddress == "0000")
                        {
    
                            endAddress = Convert2Hex(startExtendedAddress + endDataAddress) + Convert2Hex(lastDataLength) - 1;//Get the termination address
                            dataLength = endAddress - startAddress + 1;
                        }
                        else
                        {
    
                            endAddress = Convert2Hex(endExtendedAddress + endDataAddress) + Convert2Hex(lastDataLength) - 1;//Get the termination address
                            dataLength = endAddress - startAddress + 1;
                        }

                        break;
                    } //文件结束标识

                    string type = currentLineData.Substring(7, 2);

                    switch (type)
                    {
    
                        case "04":
                            if (isFirstExtendedAddress)
                            {
    
                                startExtendedAddress = currentLineData.Substring(9, 4);
                                isFirstExtendedAddress = false;
                            }
                            else
                            {
    
                                endExtendedAddress = currentLineData.Substring(9, 4);
                            }
                            break;
                        case "00":
                            if (isFirstDataAddress)
                            {
    
                                startDataAddress = currentLineData.Substring(3, 4);
                                startAddress = Convert2Hex(startExtendedAddress + startDataAddress);//获得起始地址
                                isFirstDataAddress = false;
                            }
                            else
                            {
    
                                endDataAddress = currentLineData.Substring(3, 4);
                                lastDataLength = currentLineData.Substring(1, 2);//In order to get the byte length of the last line
                            }
                            break;
                        default:
                            break;

                    }

                }
            }

            HexReader.Close();
            fsRead.Close();
        }

        /// <summary>
        ///【第2步】填充数组内容
        /// </summary>
        /// <param name="hexPath">hex文件路径</param>
        /// <param name="buffer">填充的字节数组</param>
        private void FillData(string hexPath, ref byte[] buffer)
        {
    
            int lastLine_EndAddress_Real = startAddress;//The real address where the previous line ends【扩展地址+数据地址】,初始值为hex文件的起始地址
            int currentLine_StartAddress_Real = 0;//The real address where the next line starts【扩展地址+数据地址】

            string currentExtendedAddress = "0000";//The current extension address
            string currentLineDataAddress = "0000";//Current data address

            int current_BufferIndex = 0;

            FileStream fsRead = new FileStream(hexPath, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader HexReader = new StreamReader(fsRead); //读取数据流


            while (true)
            {
    
                string currentLineData = HexReader.ReadLine(); //读取Hex中一行
                if (currentLineData == null) {
     break; } //读取完毕,退出
                if (currentLineData.Substring(0, 1) == ":") //Determine the first character is”:”
                {
    
                    //文件结束标识
                    if (currentLineData.Substring(1, 8) == "00000001")
                    {
    
                        break;
                    } 

                    string type = currentLineData.Substring(7, 2);//读取当前行的类型

                    switch (type)
                    {
    
                        case "04":
                            currentExtendedAddress = currentLineData.Substring(9, 4);
                            break;
                        case "00":
                            currentLineDataAddress = currentLineData.Substring(3, 4);//Current data address

                            currentLine_StartAddress_Real = Convert2Hex(currentExtendedAddress + currentLineDataAddress);//Actual start address value

                            //If the start address of this time is not equal to the next address of the last end,则填充"0x00"
                            if (currentLine_StartAddress_Real != lastLine_EndAddress_Real)
                            {
    
                                for (int i = 0; i < currentLine_StartAddress_Real - lastLine_EndAddress_Real; i++) // fill-in position
                                {
    
                                    byte value = byte.Parse("00", NumberStyles.HexNumber);
                                    buffer[current_BufferIndex] = value;
                                    current_BufferIndex++;
                                }
                            }

                            int currentLine_DataLength = Convert2Hex(currentLineData.Substring(1, 2));//Get the data length of the current row

                            for (int i = 0; i < currentLine_DataLength; i++)
                            {
    
                                byte value = byte.Parse(currentLineData.Substring(i * 2 + 9, 2), NumberStyles.HexNumber);
                                buffer[current_BufferIndex] = value;
                                current_BufferIndex++;
                            }

                            lastLine_EndAddress_Real = currentLine_StartAddress_Real + currentLine_DataLength;

                            break;
                        default:
                            break;

                    }

                }
            }

            //关闭Stream和文件
            HexReader.Close();
            fsRead.Close();

            //hexThe file doesn't have it at the endbyte填充“00”
            if (buffer.Length > current_BufferIndex)
            {
    
                for (int i = 0; i < buffer.Length - current_BufferIndex; i++)
                {
    
                    byte value = byte.Parse("FF", NumberStyles.HexNumber);
                    buffer[current_BufferIndex + i] = value;
                }
            }
        }

        /// <summary>
        /// 【第3步】Write the array tobin文件
        /// </summary>
        /// <param name="binPath">新建bin文件的路径</param>
        /// <param name="buffer">Byte array to write</param>
        /// <param name="startIndex">开始索引</param>
        /// <param name="length">Length of bytes written</param>
        private void WritetoBinFile(string binPath, byte[] buffer, int startIndex, int length)
        {
    
            FileStream fsWrite = new FileStream(binPath, FileMode.Create, FileAccess.Write);//If a file with the same filename already exists,delete the previous one,创建新的文件!!!
            fsWrite.Write(buffer, startIndex, length);
            fsWrite.Close();
        }


        /// <summary>
        /// 16进制字符串 转化为数值
        /// </summary>
        /// <param name="content">16进制字符串</param>
        /// <returns></returns>
        private int Convert2Hex(string content)
        {
    
            return Convert.ToInt32(content, 16);
        }
    }
}

在这里插入图片描述

测试用的hex文件

链接:https://pan.baidu.com/s/1p1aciL2108ABdZcTqZhXew
提取码:0t67

Test1_noSegment.hex说明:
在这里插入图片描述
Test1_noSegment.hex和Test2_haveSegment.hex对比:
在这里插入图片描述


参考:https://blog.csdn.net/ZF_C_CQUPT/article/details/52676716

原网站

版权声明
本文为[bright as noon]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/222/202208102101250847.html