JAVA对象转字节数组
日常使用中, 存在一些场景需要把java对象转为字节数组。 或者字节数组转java对象。 一般来说有以下几种场景。
我们来分别讨论。
1. JAVA之间相互通讯场景
这种场景常见于java应用之间的通讯, 比如A应用向B应用获取数据。 或者读取B应用预先存的数据。
此时一般来说实体类实现java自带的序列化接口, 然后使用以下方式即可完成序列化。
private Object byteToObject( byte[] bytes) {java.lang.Object obj;try {//bytearray to objectByteArrayInputStream bi = new ByteArrayInputStream(bytes);ObjectInputStream oi = new ObjectInputStream(bi);obj = oi.readObject();bi.close();oi.close();}catch(Exception ae) {throw ae;}return obj;}public byte[] objectToByte(Object obj){byte[] bytes;try {ByteArrayOutputStream bo = new ByteArrayOutputStream();ObjectOutputStream oo = new ObjectOutputStream(bo);oo.writeObject(obj);bytes = bo.toByteArray();bo.close();oo.close(); }catch(Exception ae) {throw ae;}return(bytes);}
此种方式适合java语言之间的通讯或者数据交互。不适合跨语言。而且也不适合于IM场景。
2. 仅仅做数据储存方案
储存方案一般来说要区分是否跨语言, 数据储存体积, 读取效率等问题。 这种建议优先采用文本化协议比较好(比如json, xml等), 方便开发者校验和开发。 如果使用二进制储存, 虽然体积小了。但是不方便开发和核对。出了bug不方便排查。
3. 跨语言通讯场景
跨语言通讯场景一般是最多的, 比如物联网。 IM通讯, 视频等等。由于业务的特殊性,所以一般会采用二进制协议。而且是私有协议居多。在进行序列化时候。java自带的序列化机制并不能很好的满足我们的需求。这个时候就需要用户自己手动进行序列化过程。
主要使用到 java的 ByteBuffer.
public class Student {byte height;int age;long phone;}public static void main(String[] args) {Student student = new Student();student.height = (byte) 185;student.age = 23;student.phone = 18380330237L;// 对象序列化到字节数组ByteBuffer byteBuffer = ByteBuffer.allocate(100).order(ByteOrder.BIG_ENDIAN);byteBuffer.put(student.height);byteBuffer.putInt(student.age);byteBuffer.putLong(student.phone);byte[] array = byteBuffer.array();// 字节数组序列化到对象byteBuffer = ByteBuffer.allocate(100).order(ByteOrder.BIG_ENDIAN);byteBuffer.put(array);byteBuffer.position(0);Student student2 = new Student();student2.height = byteBuffer.get();student2.age = byteBuffer.getInt();student2.phone = byteBuffer.getLong();}
上面的代码中, 列举出了我们平时序列化的方式。虽然使用字节数组可以高效率的完成对象的封装和转换。 但是需要注意以下问题:
- 字节数组大小端双方一定要一致
- 如果存在list, array 等属性, 要注意OOM
- buffer使用时如果时directbuffer, 需要注意OOM
- 注意序列化时空指针和默认值的处理
- 序列化数组不全时,注意数据对齐进行填补
- 处理 字符串时,注意字符编码集
其实跨语言通讯和私有协议这种场景,大都是大厂最先遇到并提出解决方案的。比如google 的 javastruct(2004年就出来了); 或者 magic-byte;
如果使用框架,以上的代码可以如下写了(注意类的定义和上面有所不同):
@MagicClass(byteOrder = ByteOrder.BIG_ENDIAN)public class Student {@MagicField(order = 1)byte height;@MagicField(order = 2)int age;@MagicField(order = 3)long phone;// gettter setter}public static void main(String[] args) {Student student = new Student();student.height = (byte) 185;student.age = 23;student.phone = 18380330237L;// 对象序列化到字节数组byte[] array = MagicByte.unpackToByte(student);// 字节数组序列化到对象Student student2 = MagicByte.pack(array, Student.class);}
在定义类时, 即把序列化方式定义完成。然后只需要调用函数即可进行序列化和反序列化了。
怎么样, 这样是不是简单多了。
附上开源项目的地址:
GitHub - MisterChangRay/magic-byte: faster convert byte to java object toolhttps://github.com/MisterChangRay/magic-byte
以上就是总结的一些java 对象转字节的方式。 大家按需索取吧。
JAVA对象转字节数组相关推荐
- java字符串的字节数组_Java字节数组到字符串到字节数组
我正在尝试将byte []转换为字符串,将byte []的字符串表示形式转换为byte []的转换...我将byte []转换为要发送的字符串,然后我期望我的Web服务(用python编写)将数据直接 ...
- java 字节数组作用_这段java代码中字节数组b起到了什么作用?
importjava.io.*;importjavax.swing.*;publicclassIOMonitor{publicstaticvoidmain(String[]temp){//TODO自动 ...
- java对象与byte[]数组之间的相互转化,压缩解压缩操作
下面介绍一下java对象之间和byte[]数组之间的相互转化.并对byte[]数据进行压缩操作.java对象转化为byte[]数组可用于redis中实现缓存.(这里暂不做介绍).话不多说直接开实例: ...
- Java语言对字节数组截取指定长度
Java通过 arraycopy来实现字节数组截取,类比于C语言memcpy,代码如下: System.arraycopy(src, srcPos, dest, destPos, length);参数 ...
- java字符串转换成字节数组_将Java字符串转换为字节数组
我有一个要加密的字节数组,然后转换为字符串,以便可以传输. 当我收到字符串时,我必须将字符串转换回字节数组,以便可以对其进行解密. 我检查了接收到的字符串是否与发送的字符串(包括长度)匹配,但是当我使 ...
- JAVA——实现把字节数组转成字符串
* String类 * 构造方法public String(byte[] bytes) : 把字节数组转成字符串 代码如下: public class FileInputStreamDemo3 {pu ...
- bytearray java_详解Java中ByteArray字节数组的输入输出流的用法
ByteArrayInputStream 介绍ByteArrayInputStream 是字节数组输入流.它继承于InputStream. 它包含一个内部缓冲区,该缓冲区包含从流中读取的字节:通俗点说 ...
- java 如何操作字节数组_实例解析Java字节数组操作模式代码
字节数组的关键是它为存储在这部分内存中的每个8位值提供索引(快速)和精确的原始访问,并且您可以操纵这些字节来控制每个位.缺点是计算机只将每个条目视为一个独立的8位数字--这可能是您的程序正在处理的,或 ...
- Java:GB18030字节数组与UTF8互转
2019独角兽企业重金招聘Python工程师标准>>> JDK:1.8 当我们需要把一个以GB18030编码的字节数组转换为UTF8字符串,我们可以使用nio中的编解码. 1.GB1 ...
最新文章
- Camel之AsyncProcessor
- Zend Studio出现 Some characters cannot be mapped using GBK character encoding 错误
- 制作linux安装镜像文件,制作CentOS 6.5一键自安装ISO镜像光盘 | 聂扬帆博客
- [原创]换一份工作要考虑什么?
- t3 修改服务器配置,t3如何修改服务器地址
- 如何在 C# 中使用隐式和显式操作符
- 整理Linux查看系统日志的一些经常使用命令
- python旋转数组_Python3实现旋转数组的3种算法
- BZOJ 1646: [Usaco2007 Open]Catch That Cow
- 使用stanford nlp进行依存句法分析
- 面向对象——类设计(一)
- python狗屁不通文章生成器_狗屁不通文章生成器,哈哈哈
- 鼠标不受控制一直向右移动的解决办法
- php tp框架面试问题,Thinkphp面试问题及答案
- 浙江大学-研究生机器学习课程-课堂笔记
- 矢量网络分析仪的基本原理
- 大会没看够?2021 Google 开发者大会总结看这里!
- 锋迷商城spring-vue项目流程和笔记
- 下列内容属于计算机房控制功能的是,前厅服务员中级理论知识试卷及答案2
- AlarmManager 中 setRepeating用法