package com.dy.common.softUpgrade.parse; import cn.hutool.core.util.HexUtil; import com.dy.common.util.ByteUtil; import java.io.*; import java.util.List; import java.util.stream.Stream; /** * @Author: liurunyu * @Date: 2024/11/2 8:51 * @Description */ public class HexFileParse { private static final int hexFileMinLine = 4 ; private static final int lineHeadEndIndex = 9 ; private static final int bytesSplitUnit = 512 ; public static void main(String[] args) throws Exception{ boolean fromBytes = true ; HexFileParse obj = new HexFileParse() ; if(!fromBytes){ String filePath = "D:\\hexFile\\YuanMu_edit241007_01.hex"; //File file = new File(filePath) ; HexFileVo vo = obj.doParse(filePath) ; System.out.println(vo.toString()); }else{ String filePath = "D:\\hexFile\\YuanMu_edit241007_01.hex"; File file = new File(filePath) ; byte[] fileContent = new byte[(int)file.length()] ; FileInputStream fileInputStream = new FileInputStream(file) ; fileInputStream.read(fileContent) ; HexFileVo vo = obj.doParse(fileContent) ; System.out.println(vo.toString()); } } /** * 解析Hex文件 * @param path * @return * @throws Exception */ public HexFileVo doParse(String path) throws Exception { File file = new File(path) ; return this.doParse(file) ; } /** * 解析Hex文件 * @param file * @return * @throws Exception */ public HexFileVo doParse(File file) throws Exception{ if(file == null){ throw new Exception("Hex文件对象为null") ; } if(!file.exists()){ throw new Exception("Hex文件不存在") ; } Stream linesStream = new BufferedReader(new FileReader(file)).lines() ; List lineList = linesStream.toList() ; HexFileVo vo = new HexFileVo() ; this.checkAndCalculate(vo, lineList); this.parse(vo, lineList); this.split(vo); return vo ; } /** * 解析Hex文件 * @param fileContent * @return * @throws Exception */ public HexFileVo doParse(byte[] fileContent) throws Exception{ if(fileContent == null || fileContent.length == 0){ throw new Exception("Hex文件对象为null") ; } ByteArrayInputStream byteInputStream = new ByteArrayInputStream(fileContent); Stream linesStream = new BufferedReader(new InputStreamReader(byteInputStream)).lines() ; List lineList = linesStream.toList() ; HexFileVo vo = new HexFileVo() ; this.checkAndCalculate(vo, lineList); this.parse(vo, lineList); this.split(vo); return vo ; } /** * 合法性检查,并计算数据包数 * @param vo * @param lineList * @throws Exception */ private void checkAndCalculate(HexFileVo vo, List lineList) throws Exception{ if(lineList == null){ throw new Exception("Hex文件内容为空") ; } vo.totalLines = lineList.size() ; if(vo.totalLines <= 0){ throw new Exception("Hex文件内容为空") ; } if(vo.totalLines < hexFileMinLine){ throw new Exception("Hex文件内容行数" + vo.totalLines + "不正确(最小行数" + hexFileMinLine +")") ; } vo.calculateBytes = ((vo.totalLines - 4) * 32) / 1024 * 512 ; } /** * 解析Hex文件内容,组合成一个大数据包 * @param vo * @param lineList * @throws Exception */ private void parse(HexFileVo vo, List lineList) throws Exception{ int counter = 0 ; for(String line : lineList){ if(counter == 0){ // 文件头 }else if(counter == vo.totalLines - 2){ // 文件尾倒数第2行 }else if(counter == vo.totalLines - 1){ // 文件尾倒数第1行 }else{ // 文件内容 if(line == null){ vo.errors.add("第" + counter + "行内容为空") ; }else{ line = line.trim() ; if(line.length() == 0){ vo.errors.add("第" + counter + "行内容为空") ; }else{ if(!line.startsWith(":")){ vo.errors.add("第" + counter + "行内容不是以:开头") ; }else{ line = line.substring(lineHeadEndIndex, line.length() - 2) ; if(vo.bytes.length == 0){ vo.bytes = HexUtil.decodeHex(line) ; }else{ byte[] bytes = HexUtil.decodeHex(line) ; vo.bytes = ByteUtil.bytesMerge(vo.bytes, bytes) ; } } } } } counter ++ ; } } /** * 以512为单位分割数据包 * @param vo */ private void split(HexFileVo vo){ if(vo.bytes != null && vo.bytes.length > 0){ vo.realBytes += vo.bytes.length ; int index = 0 ; while (true){ if(index < vo.bytes.length){ byte[] bytes = ByteUtil.bytesSplit(vo.bytes, index, bytesSplitUnit) ; vo.listByte512.add(bytes) ; vo.totalBytes512 += bytes.length ; }else{ break ; } index += bytesSplitUnit ; } } } }