Java--序列化與反序列化

BtWangZhi發表於2017-10-05

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());
    }
}

相關文章