| | |
| | | |
| | | import cn.hutool.core.util.HexUtil; |
| | | import com.dy.common.util.ByteUtil; |
| | | import com.dy.common.util.CRC16; |
| | | |
| | | import java.io.*; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.stream.Stream; |
| | | |
| | |
| | | |
| | | private static final int hexFileMinLine = 4 ; |
| | | private static final int lineHeadEndIndex = 9 ; |
| | | private static final int bytesSplitUnit = 512 ; |
| | | private static final int lineValidCharCount = 43 ;//每行有效字符(冒号与十六进制)个数,例如“:1096C000DC96010010020020203E00000441000052”,但倒数第3行不受限制 |
| | | private static final int bytesSplitUnit512 = 512 ; |
| | | |
| | | public static void main(String[] args) throws Exception{ |
| | | boolean fromBytes = true ; |
| | | boolean fromBytes = false ; |
| | | HexFileParse obj = new HexFileParse() ; |
| | | if(!fromBytes){ |
| | | String filePath = "D:\\hexFile\\YuanMu_edit241007_01.hex"; |
| | | String filePath = "D:\\hexFile\\YuanMu_20250116_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"; |
| | | String filePath = "D:\\hexFile\\YuanMu_20250116_01.hex"; |
| | | File file = new File(filePath) ; |
| | | byte[] fileContent = new byte[(int)file.length()] ; |
| | | FileInputStream fileInputStream = new FileInputStream(file) ; |
| | |
| | | HexFileVo vo = new HexFileVo() ; |
| | | this.checkAndCalculate(vo, lineList); |
| | | this.parse(vo, lineList); |
| | | this.split(vo); |
| | | this.splitBytesByUnit512(vo); |
| | | this.calculateCrc(vo); |
| | | return vo ; |
| | | } |
| | | |
| | |
| | | HexFileVo vo = new HexFileVo() ; |
| | | this.checkAndCalculate(vo, lineList); |
| | | this.parse(vo, lineList); |
| | | this.split(vo); |
| | | this.splitBytesByUnit512(vo); |
| | | this.calculateCrc(vo); |
| | | return vo ; |
| | | } |
| | | |
| | |
| | | if(vo.totalLines < hexFileMinLine){ |
| | | throw new Exception("Hex文件内容行数" + vo.totalLines + "不正确(最小行数" + hexFileMinLine +")") ; |
| | | } |
| | | vo.calculateBytes = ((vo.totalLines - 4) * 32) / 1024 * 512 ; |
| | | vo.calculateBytes = ((((vo.totalLines - 4) * 32) / 1024) |
| | | + ((((vo.totalLines - 4) * 32) % 1024) > 0?1 : 0)) |
| | | * 512 ; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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) ; |
| | | if(counter != vo.totalLines - 3 && line.length() != lineValidCharCount){ |
| | | //无效数据,舍弃本行数据 |
| | | }else{ |
| | | byte[] bytes = HexUtil.decodeHex(line) ; |
| | | vo.bytes = ByteUtil.bytesMerge(vo.bytes, bytes) ; |
| | | 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) ; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 以512为单位分割数据包 |
| | | * @param bytes |
| | | */ |
| | | public List<byte[]> splitBytesByUnit512(byte[] bytes){ |
| | | List<byte[]> listByte512 = new ArrayList<>(); |
| | | if(bytes != null && bytes.length > 0){ |
| | | int index = 0 ; |
| | | while (true){ |
| | | if(index < bytes.length){ |
| | | byte[] bs = ByteUtil.bytesSplit(bytes, index, bytesSplitUnit512) ; |
| | | listByte512.add(bs) ; |
| | | }else{ |
| | | break ; |
| | | } |
| | | index += bytesSplitUnit512; |
| | | } |
| | | } |
| | | return listByte512 ; |
| | | } |
| | | |
| | | /** |
| | | * 以512为单位分割数据包 |
| | | * @param vo |
| | | */ |
| | | private void split(HexFileVo vo){ |
| | | private void splitBytesByUnit512(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) ; |
| | | byte[] bytes = ByteUtil.bytesSplit(vo.bytes, index, bytesSplitUnit512) ; |
| | | vo.listByte512.add(bytes) ; |
| | | vo.totalBytes512 += bytes.length ; |
| | | }else{ |
| | | break ; |
| | | } |
| | | index += bytesSplitUnit ; |
| | | index += bytesSplitUnit512; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 计算CRC16 |
| | | * @param vo |
| | | */ |
| | | private void calculateCrc(HexFileVo vo){ |
| | | int crc = 0xffff ; |
| | | if(vo.listByte512 != null && vo.listByte512.size() > 0){ |
| | | CRC16 crc16 = new CRC16() ; |
| | | for(byte[] bs : vo.listByte512){ |
| | | crc = crc16.CRC16_table(bs.length, bs, crc) ; |
| | | } |
| | | } |
| | | vo.bytesCrc16 = crc ; |
| | | } |
| | | |
| | | } |