天天看點

Java中 對象和二進制數組(byte array)之間的互轉

直接上代碼
package com.study.auth.config.core.handler;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.Arrays;
import java.util.Objects;

/**
 * @Package: com.study.auth.config.core.handler
 * @Description: <對象和二進制數組及流對象間的轉換>
 * @Author: milla
 * @CreateDate: 2020/09/09 09:52
 * @UpdateUser: milla
 * @UpdateDate: 2020/09/09 09:52
 * @UpdateRemark: <>
 * @Version: 1.0
 */
@Slf4j
public class ByteArrayUtil {
    public static void main(String[] args) {
        Student student = new Student("馮程程", "上海金融大街", 23, "女");
        byte[] array = toByteArray(student);
        System.out.println("位元組數組:" + Arrays.toString(array));
        ByteArrayOutputStream arrayOutputStream = toOutputStream(student);
        System.out.println("輸出流: " + arrayOutputStream);

        Student obj = toObject(array, Student.class);
        Student obj1 = toObject(arrayOutputStream, Student.class);

        System.out.println("位元組數組轉換成對象:" + obj);
    }

    /**
     * 将ByteArrayOutputStream輸出流轉換成對象
     *
     * @param outputStream 輸出流
     * @param clazz        要轉話程的對象class檔案
     * @param <T>          要轉化的對象
     * @return
     */
    public static <T> T toObject(ByteArrayOutputStream outputStream, Class<T> clazz) {
        if (Objects.isNull(outputStream)) {
            log.error("outputStream array can not be null");
            return null;
        }
        byte[] data = outputStream.toByteArray();
        return toObject(data, clazz);
    }

    /**
     * 将輸入流轉換成對象
     *
     * @param inputStream 輸入流
     * @param clazz       要轉換成對象的class檔案
     * @param <T>         要轉換程的對象類型
     * @return
     */
    public static <T> T toObject(InputStream inputStream, Class<T> clazz) {
        if (Objects.isNull(inputStream)) {
            log.error("inputStream array can not be null");
            return null;
        }
        ObjectInputStream obj = null;
        try {
            obj = new ObjectInputStream(inputStream);
            return (T) obj.readObject();
        } catch (IOException | ClassNotFoundException e) {
            log.error("byte array to {} failed: {}", clazz.getName(), e);
            return null;
        } finally {
            try {
                if (Objects.nonNull(inputStream)) {
                    inputStream.close();
                }
                if (Objects.nonNull(obj)) {
                    obj.close();
                }
            } catch (IOException e) {
                log.error("stream close failed: {}", e);
            }

        }
    }

    /**
     * 将byte數組轉換成對象
     *
     * @param array byte數組
     * @param clazz 要轉成的對象位元組碼
     * @param <T>   要轉成的類型
     * @return
     */
    public static <T> T toObject(byte[] array, Class<T> clazz) {
        if (Objects.isNull(array) || array.length == 0) {
            log.error("byte array can not be null");
            return null;
        }
        ByteArrayInputStream bis = new ByteArrayInputStream(array);
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(bis);
            return (T) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            log.error("byte array to {} failed: {}", clazz.getName(), e);
            return null;
        } finally {
            try {
                if (Objects.nonNull(bis)) {
                    bis.close();
                }
                if (Objects.nonNull(ois)) {
                    ois.close();
                }
            } catch (IOException e) {
                log.error("stream close failed: {}", e);
            }

        }
    }

    /**
     * 将對象抓換成二進制對象
     * Ps:對象必須實作Serializable接口,最好能給定一個serialVersionUID
     *
     * @param data 對象
     * @return
     */
    public static byte[] toByteArray(Object data) {
        ByteArrayOutputStream outputStream = toOutputStream(data);
        if (Objects.isNull(outputStream)) {
            return null;
        }
        return outputStream.toByteArray();
    }

    /**
     * 将對象轉換成輸出流
     * Ps:對象必須實作Serializable接口,最好能給定一個serialVersionUID
     *
     * @param data 對象
     * @return
     */
    public static ByteArrayOutputStream toOutputStream(Object data) {
        if (Objects.isNull(data)) {
            log.error("{} can not be null", data.getClass().getName());
            return null;
        }
        ByteArrayOutputStream array = new ByteArrayOutputStream();
        ObjectOutputStream objectWrite = null;
        try {
            objectWrite = new ObjectOutputStream(array);
            objectWrite.writeObject(data);
            objectWrite.flush();
            return array;
        } catch (IOException e) {
            log.error("{} to byte array failed: {}", data.getClass().getName(), e);
            return null;
        } finally {
            try {
                if (Objects.nonNull(array)) {
                    array.close();
                }
                if (Objects.nonNull(objectWrite)) {
                    objectWrite.close();
                }
            } catch (IOException e) {
                log.error("stream close failed: {}", e);
            }
        }
    }

}

@Data
class Student implements Serializable {
    /**
     * 序列化/反序列化必須實作Serializable接口
     * 想要不出現類型轉換異常就需要有一個統一的serialVersionUID
     */
    private static final long serialVersionUID = 7824278330465676953L;

    private String name;
    private String address;
    private Integer age;
    private String sex;

    public Student(String name, String address, Integer age, String sex) {
        this.name = name;
        this.address = address;
        this.age = age;
        this.sex = sex;
    }
}
           
 必要的依賴
<dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.18.12</version>
   </dependency>
           
 PS::
  1.  對象一定要實作Serializable接口,否則不具備轉換的基礎條件
  2. 和對象序列化一樣,如果對象有修改的可能一定要定義一個唯一serialVersionUID