1 序列化即将Java对象转为二进制流
public static void main(String[] args) throws Exception {
byte[] bytes = toBytes();
toObject(bytes);
}
/**
* 对象序列化成字节码
*
* @return
* @throws IOException
*/
public static byte[] toBytes() throws IOException {
User user = new User(11, "张三", "123");
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
byteOutputStream);
// 写入对象
objectOutputStream.writeObject(user);
// 获取字节数组
byte[] byteArray = byteOutputStream.toByteArray();
return byteArray;
}
/**
* 反序列化对象
*
* @param buff
* @return
* @throws Exception
*/
public static Object toObject(byte[] buff) throws Exception {
ObjectInputStream inputStream = new ObjectInputStream(
new ByteArrayInputStream(buff));
User user = (User) inputStream.readObject();
// 打印对象信息
System.out.println(user.getId()+" "+user.getName()+""+user.getPassword());
return user;
}
/**
* 对象
* @author Tang
*
*/
public static class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String password;
public User(Integer id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
//省略get set方法
}
}
2 自定义序列化
2.1 采用位移运算
public class Text01 {
public static void main(String[] args) throws IOException {
int id = 101;
int age = 21;
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
arrayOutputStream.write(int2Bytes(id));
arrayOutputStream.write(int2Bytes(age));
byte[] byteArray = arrayOutputStream.toByteArray();
System.out.println(Arrays.toString(byteArray));
System.out.println("-------------------------");
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(
byteArray);
byte[] idBytes = new byte[4];
arrayInputStream.read(idBytes);
System.out.println("id:" + bytes2Int(idBytes));
byte[] ageBytes = new byte[4];
arrayInputStream.read(ageBytes);
System.out.println("id:" + bytes2Int(ageBytes));
}
/**
* 百度--大小端字节序列
*
* @param i
* @return
*/
public static byte[] int2Bytes(Integer i) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (i >> 3 * 8);
bytes[1] = (byte) (i >> 2 * 8);
bytes[2] = (byte) (i >> 1 * 8);
bytes[3] = (byte) (i >> 0 * 8);
return bytes;
}
/**
* 大端数据
*
* @return
*/
public static Integer bytes2Int(byte[] bytes) {
return (bytes[0] << 3 * 8) | (bytes[1] << 2 * 8) | (bytes[2] << 1 * 8)
| (bytes[3] << 0 * 8);
}
}
2.2 使用NIO,缺点是由于ByteBuffer.allocate(8)分配的空间不会自动扩容,可能会出现异常
public class Text02 {
public static void main(String[] args){
int id=101;
int age=21;
ByteBuffer buffer=ByteBuffer.allocate(8);//不会自动扩容
buffer.putInt(id);
buffer.putInt(age);
//序列化数据
byte[] array = buffer.array();
System.out.println(Arrays.toString(buffer.array()));
//反序列化
ByteBuffer buffer2=ByteBuffer.wrap(array);
System.out.println("id:"+buffer2.getInt());
System.out.println("age:"+buffer2.getInt());
}
}
2.3 使用Netty,Netty中的ChannelBuffers.dynamicBuffer()分配的大小空间能自动扩容。
public class Text03 {
public static void main(String[] args){
ChannelBuffer buffer=ChannelBuffers.dynamicBuffer();//可自动扩容
buffer.writeInt(101);
buffer.writeDouble(80.1);
byte[] bytes=new byte[buffer.writerIndex()];
buffer.readBytes(bytes);
System.out.println(Arrays.toString(bytes));
ChannelBuffer wrappedBuffer = ChannelBuffers.wrappedBuffer(bytes);
System.out.println("id:"+wrappedBuffer.readInt()+"age:"+wrappedBuffer.readDouble());
}
}