一、为什么需要将object转化为byte数组
在数据的传输和存储过程中,我们常常需要将对象转化为byte数组。这主要是因为在网络传输、磁盘存储、对象序列化等场景中,byte数组具有以下几个优点:
1、在各种机器和系统之间传输数据的唯一通用方式就是将数据转换成byte数组
2、byte数组在JAVA和.NET等主流编程语言中被广泛的使用
3、更加灵活处理数据
示例代码:
public static byte[] objectToByteArray(Object obj) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.writeObject(obj);
return out.toByteArray();
}
二、如何实现object转byte数组
实现将object转化为byte数组的方法基本上分为两个方案:
1、使用Java序列化机制,将目标对象序列化为byte数组
2、手工编写二进制转换工具类,将目标对象按照特定的顺序转换为byte数组
使用第一个方案的好处是,无需考虑数据存储结构和数据类型,因为Java序列化机制会自动处理这些问题。
另一方面,由于Java序列化机制是重量级的,一些对象序列化时会存在性能问题,例如大量的计算和IO连续读写。
示例代码:
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
return bos.toByteArray();
}
三、如何反序列化byte数组为object
如果要将byte数组转换回对象,必须将byte数组还原为原始的Java对象。
示例代码:
public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
四、如何处理非序列化对象
在某些情况下,对象可能无法进行Java序列化,此时可以使用手工编写的转换工具类将对象转换为byte数组。
示例代码:
public static byte[] toByteArray(String s) {
try {
byte[] data = s.getBytes("ISO-8859-1");
int len = data.length;
byte[] out = new byte[len];
for (int i = 0; i < len; i++) {
out[i] = data[i];
}
return out;
} catch (UnsupportedEncodingException e) {
return null;
}
}
五、如何处理序列化对象中的特殊情况
在某些情况下,序列化对象可能会遇到一些特殊情况,例如:
1、序列化的对象含有敏感信息,需要忽略这部分信息
2、序列化时出现循环应用,需要正常转换
示例代码:
public class CustomObjectOutputStream extends ObjectOutputStream {
public CustomObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {
return;
}
@Override
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
return;
}
}
六、遇到byte数组转object卡顿咋办
当byte数组非常大时,将byte数组转化为object可能会非常耗时。
一种简单的解决方法是,将byte数组分割成多个部分,然后逐步转换为不同的object。
示例代码:
public static List<Object> splitArray(Object[] array, int chunkSize) {
List<Object> listOfArrays = new ArrayList<Object>();
int totalSize = array.length;
int offset = 0;
while (totalSize > 0) {
int length = Math.min(totalSize, chunkSize);
Object subArray = Array.newInstance(array.getClass().getComponentType(), length);
System.arraycopy(array, offset, subArray, 0, length);
offset += length;
totalSize -= length;
listOfArrays.add(subArray);
}
return listOfArrays;
}
七、如何进行序列化和反序列化的性能测试
如何进行Java序列化和反序列化的性能测试?目前最常用的是使用jmh测试框架:JMH 是用于基准测试的 Java Microbenchmark Harness,是 OpenJDK 工具集的一部分,提供了简单而强大的基准测试方法。它的使用方式类似JUnit,基于注解构建并运行测试。
示例代码:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(value = 1, jvmArgs = {"-Xms2G", "-Xmx2G"})
@Warmup(iterations = 3)
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
public class SerializationTest {
private static final byte[] DATA = createData();
private static final Serializable OBJECT = new MyObject();
private static byte[] createData() {
Random random = new Random();
byte[] data = new byte[1024 * 1024];
random.nextBytes(data);
return data;
}
@Benchmark
public byte[] serialize() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(OBJECT);
return bos.toByteArray();
}
@Benchmark
public Object deserialize() throws IOException, ClassNotFoundException {
ByteArrayInputStream bis = new ByteArrayInputStream(serialize());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
原创文章,作者:BLKNA,如若转载,请注明出处:https://www.506064.com/n/325047.html
微信扫一扫
支付宝扫一扫