hex 文件的格式,以文件中某一行字符串(16进制)为例:

:10 0830 00 020C5D0224B3FFFFFFFFFFFFFFFFFFFF 7E

10,长度,转换成10进制,也就是16B 大小,这里是32个字符,因为16进制中,2个字符占一个字节,可以不管。
0830,地址,转换成10进制好计算,数据存入字节数组时,可以当做数组下标来使用,方便计算两个地址间的差值。
00,这里表示数据记录,还有其他类型百度便知,可以不管。
02...FF,数据部分。主要就是把这一部分转成bin文件。
7E,校验使用。

新建一个java工程加入以下代码如有问题请留言

import com.mpos.init.model.FileStruct;
import com.mpos.init.model.HexRec; import java.io.*;
import java.util.ArrayList;
import java.util.List; public class Test { public static void main(String[] args) {
System.out.println(readFile() + "");
} /**
* @return -1 文件解析错误 0 表示成功 -2 初始buf太小
*/
private static int readFile() {
File mfile = new File("D:\\MP100-01-V1.2-20180115.hex");
List<HexRec> hexRecs = new ArrayList<>();
InputStream inputStream = null;
BufferedReader bufferedReader = null;
FileOutputStream fileOutputStream = null;
int i = 0, j = 0; //索引
int l_addr;
int len = 0;//数组索引
long minAddr = 4294967295L;
FileStruct hex = new FileStruct();
try {
if (mfile == null) {
System.out.println("文件为空");
}
inputStream = new FileInputStream(mfile);
//转成 reader 以 行 为单位读取文件
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//当前行字符串
String hexLineStr;
//当前行数
int hexLineNum = 0;
while ((hexLineStr = bufferedReader.readLine()) != null) {
System.out.println(hexLineStr);
hexLineNum++;
if (!hexLineStr.startsWith(":", 0)) {
return -1;
}
if (hexLineStr.length() >= 11) {
hex.setStart(":");
byte[] data = hexString2ByteArray(hexLineStr.substring(1));//判断数据的正确是是不是0—F
if (data == null) return -1;
//解析数据
hex.setLength(Integer.parseInt(hexLineStr.substring(1, 3), 16));
hex.setOffset(Integer.parseInt(hexLineStr.substring(3, 7), 16));
hex.setType(Integer.parseInt(hexLineStr.substring(7, 9), 16));
///////////////////////////////////////////////////////////////////
//判断数据类型是否合法, 未处理05的数据
if (0x00 != hex.getType() && 0x01 != hex.getType() && 0x02 != hex.getType() && 0x04 != hex.getType() && 0x05 != hex.getType()) {
return -1;
}
if (0x05 == hex.getType()) {//不处理05类型的数据
continue;
}
if (hex.getLength() > 0) {
hex.setData(hexLineStr.substring(9, 9 + hex.getLength() * 2));
}
if (!checkValue(hexLineStr)) return -1;
switch (hex.type) {
case 0x00: //本行的数据类型为“数据记录”
//本行所从属的数据类型为“数据记录”
if (0x00 == hex.format) {
l_addr = hex.offset;
}
//本行所从属的数据类型为“扩展段地址记录”(HEX86)--20位地址
else if (0x02 == hex.format) {
l_addr = (hex.address << 4) + hex.offset;
}
//本行所从属的数据类型为“扩展线性地址记录”(HEX386)--32位地址
else if (0x04 == hex.format) {
l_addr = (hex.address << 16) + hex.offset;
}
//文件结束
else {
i = 1;
break;
}
//记录地址中的最大值
System.out.println("l_addr:" + l_addr);
if (minAddr > l_addr) minAddr = l_addr;
if (hex.length > 0) {
HexRec hexRec = new HexRec();
hexRec.setAddr(l_addr);
hexRec.setLen(hex.length);
hexRec.setBuf(hex.data);
hexRecs.add(hexRec);
len += hex.length;
}
break; case 0x01: //本行的数据类型为“文件结束记录”
//文件结束记录的数据个数一定是0x00
if (hex.length == 0x00) i = 1;
hex.format = 0x01;
break; case 0x02: //本行的数据类型为“扩展段地址记录”
//扩展段地址记录的数据个数一定是0x02
if (hex.length != 0x02) i = 3;
//扩展段地址记录的地址一定是0x0000
if (hex.offset != 0x0000) i = 3;
//更改hex从属的数据类型
hex.format = 0x02;
//获取段地址
String hexStr = hex.getData().substring(0, 4);
byte[] hexBytes = hexString2ByteArray(hexStr);
hex.address = (hexBytes[0] << 8 | hexBytes[1]);
break; case 0x04://本行的数据类型为“扩展线性地址记录”
//扩展线性地址记录中的数据个数一定是0x02
if (hex.length != 0x02) i = 4;
//扩展线性地址记录的地址一定是0x0000
if (hex.offset != 0x0000) i = 4;
//更改hex从属的数据类型
hex.format = 0x04;
//获取高16位地址
hexStr = hex.getData().substring(0, 4);
hexBytes = hexString2ByteArray(hexStr);
hex.address = (hexBytes[0] << 8 | hexBytes[1]);
break;
}
}
//如果出现异常或文件结束退出循环
if (i == 1) {
break;
}
if (i > 0) {
return -1;//文件解析出错
}
}
len = 0;
int minLen = 0;
int offset = 0;
StringBuffer buffer = new StringBuffer();
for (int a = 0; a < hexRecs.size(); a++) {
offset = (int) (hexRecs.get(a).getAddr() - minAddr);
buffer.append(hexRecs.get(a).getBuf());
if (minLen < offset + hexRecs.get(a).getLen()) {
minLen = offset + hexRecs.get(a).getLen();
}
len += hexRecs.get(a).getLen();
}
if (len < minLen) {
len = minLen;
}
System.out.println(buffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return 0;
}
/**
* 将16进制字符串转换为byte[]
*
* @param hexString
* @return
*/
public static byte[] hexString2ByteArray(String hexString) {
try {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
} catch (Exception e) {
return null;
}
} /**
* Convert char to byte
*
* @param c char
* @return byte
*/
public static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
} /**
* 校验和必然是256的整数倍,如果有余数则认为校验和失败
*
* @return false 校验失败 反正成功
*/
public static boolean checkValue(String hexLineStr) {
byte[] buf = hexString2ByteArray(hexLineStr.substring(1));
byte temp = 0;
for (int i = 0; i < buf.length; i++) {
temp += buf[i];
}
if (temp % 0xFF == 0) {
return true;
}
return false;
} }
FileStruct对象代码
public class FileStruct {
public String start = ":"; //每一条Hex记录的起始字符“:”
public int length = 0x00; //数据的字节数量
public int address = 0x0000; //数据存放的地址
public int type = 0xFF; //HEX记录的类型
public String data;//一行最多有16个字节的数据
public int check = 0xAA; //校验和
public int offset = 0x0000; //偏移量
public int format = 0x00; //数据行所从属的记录类型 public String getStart() {
return start;
} public void setStart(String start) {
this.start = start;
} public int getLength() {
return length;
} public void setLength(int length) {
this.length = length;
} public int getAddress() {
return address;
} public void setAddress(int address) {
this.address = address;
} public int getType() {
return type;
} public void setType(int type) {
this.type = type;
} public String getData() {
return data;
} public void setData(String data) {
this.data = data;
} public int getCheck() {
return check;
} public void setCheck(int check) {
this.check = check;
} public int getOffset() {
return offset;
} public void setOffset(int offset) {
this.offset = offset;
} public int getFormat() {
return format;
} public void setFormat(int format) {
this.format = format;
}
}

HexRec对象代码
public class HexRec {
private int addr;
private int len;
private String buf; public HexRec() { } public int getAddr() {
return addr;
} public void setAddr(int addr) {
this.addr = addr;
} public int getLen() {
return len;
} public void setLen(int len) {
this.len = len;
} public String getBuf() {
return buf;
} public void setBuf(String buf) {
this.buf = buf;
} }

 


java 实现hex文件转换bin保存至内存中的更多相关文章

  1. .hex文件和.bin文件的区别

    博客转之于:  http://mini.eastday.com/a/160627003502858.html HEX文件和BIN文件是我们经常碰到的2种文件格式.下面简单介绍一下这2种文件格式的区别: ...

  2. hex文件和bin文件区别

    HEX文件和BIN文件是我们经常碰到的2种文件格式.因为自己也是新手,所以一直对这两个文件懵懵懂懂,不甚了解,最近在做STM32单片机的IAP更新,其中要考虑HEX文件和BIN文件,所以需要学习下这两 ...

  3. javafx这些学会后,开发就不难了,往tablecloumn列中添加按钮,修改javafx中tableview中tablecell中的值,修改完回车表示保存到内存中

    javafx开发过程中遇见难题,往tablecloumn列中添加按钮 想了很久的方法,也配有办法判断每行中有数据的地方添加按钮set bank_caozuo.setCellFactory((col)- ...

  4. Java常量,变量,对象(字面量)在JVM内存中的存储位置

    Java常量,变量,对象(字面量)在JVM内存中的存储位置 2019-02-26 18:13:09 HD243608836 阅读数 540  收藏 更多 分类专栏: JAVA jvm   苦苦研究了快 ...

  5. PHP hex文件及bin文件读取

    背景:做物联网时经常会有软件上传这种操作,上传的软件包文件常见的是hex和bin这两种. 一 hex文件读取 1 首先我们需要了解hex文件内容格式 (图及下面说明来自网络,侵权必删) :(冒号)每个 ...

  6. java实现xml文件读取并保存到对象

    首先浅聊一下解析xml的四种方式: 1.DOM方式:有缺点但是这个缺点却也是他的优点.下面详细介绍: 以树形的层次结构组织节点或信息片断集合,可以获得同一个文档中的多处不同数据.使用起来简单. 优点是 ...

  7. java动态编译类文件并加载到内存中

    如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考这篇博文-http://www.cnblogs.com/anai/p/4270 ...

  8. java前端传入的json字符串保存到表中的方法

    表 service_goods_base 字段如下: 传入的json 字符串: servicePictureArray  :  [{"picServiceUrl": "h ...

  9. java成员变量和局部变量的初始化和内存中的运行机制

    成员变量: 当系统加载类或创建类的实例时,系统会自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值. eyeNum是类属性.name是实例属性 所有person实例访问eyeNu ...

随机推荐

  1. Node.js_简介及其 npm 包管理器基本使用_npm_cnpm_yarn_cyarn

    Node.js 既是语言也是平台,跳过了 Apache.Nginx 等 HTTP 服务器,直接面向前端开发 JavaScript 是由 ECMAScript.文档对象模型(DOM)和浏览器对象模型(B ...

  2. [LeetCode] Quad Tree Intersection 四叉树相交

    A quadtree is a tree data in which each internal node has exactly four children: topLeft, topRight,  ...

  3. 使用ngnix做服务器的负载均衡

    (1)  进程数与每个进程的最大连接数: nginx进程数,建议设置为等于CPU总核心数 单个进程最大连接数,那么该服务器的最大连接数=连接数*进程数 (2) Ngnix的基本配置 监听端口一般都为h ...

  4. Nginx基本安装

    Windows安装Nginx 解压:nginx-windows 双击: nginx.exe 能看到nginx欢迎界面说明,nginx安装成功 演示下 nginx做静态服务器 启动Nginx C:\se ...

  5. Web Service学习(一)

    1.WebMethod特性包含哪些属性,都有什么用? 1.BufferResponse属性 该属性表明是否启用对Web Service方法响应的缓冲.当设置为true时,Web Service方法将响 ...

  6. IP协议号 IP首部中有8位协议号,用于指明IP的上层协议.

    IP协议号   IP首部中有8位协议号,用于指明IP的上层协议. 0 HOPOPT IPv6 逐跳选项 1 ICMP Internet 控制消息 2 IGMP Internet 组管理 3 GGP 网 ...

  7. Sybase IQ 的基础

    Sybase IQ 的基础   Sybase IQ的一些基础总结: 1.IQ跟其它的关系型数据库相比,它的主要特征是:查询快.数据压缩比高.Load快,但是插入更新慢,不太适应数据老是变化,它是按列存 ...

  8. Linux Shell 用法

    目录 Shell test 命令 数值测试 字符串测试 文件测试 函数返回值 Shell test 命令 Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测 ...

  9. 操作系统与cpu

  10. LeetCode 606 Construct String from Binary Tree 解题报告

    题目要求 You need to construct a string consists of parenthesis and integers from a binary tree with the ...