직렬화(Serialize) 란?
- 자바 시스템 내부에서 사용되는 Object 또는 Data를 외부의 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술.
- JVM(Java Virtual Machine 이하 JVM)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 같이 이야기합니다.
- 직렬화를 통해 프로그램이 실행되는 동안 생성된 객체를 스트림을 이용해서 지속적으로 보관하거나 전송 할 수 잇다.
역직렬화(Deserialize) 란?
- byte로 변환된 Data를 원래대로 Object나 Data로 변환하는 기술을 역직렬화(Deserialize)라고 부릅니다.
- 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태
직렬화 가능한 클래스를 만드는 방법.
1) Serializable 인터페이스를 이용
//직렬화가 되어 있어야 파일에 읽고 쓸수 있는 클래스가 된다.
public class Data implements Serializable {
private int no;
private String name;
private String mail;
public Data(int no, String name, String mail) {
super();
this.no = no;
this.name = name;
this.mail = mail;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
}
2) Externalizable 인터페이스를 이용
public class Data implements Externalizable {
private int no;
private String name;
private String mail;
public Data(int no, String name, String mail) {
super();
this.no = no;
this.name = name;
this.mail = mail;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}
Externalizable 인터페이스는 Serializable 인터페이스를 확장한 형태로 세부적인 필드를 직접 제어할 수 있다.
transient 키워드를 사용하여 특정 필드를 제외시키는 것도 가능하지만 좀 더 세부적인 작업이 필요할 때 이렇게 Externalizable 인터페이스를 사용할 수 있다. 이를 위해서 이 인터페이스는 Serializable 인터페이스를 확장하고 출력을 위한 writeExternal() 메소드와 입력을 위한 readExternal() 메소드를 사용한다.
하지만 Serializable 에서 transient 키워드를 사용하는 것이 편리하기 때문에 대부분 Serializable 인터페이스를 사용한다.
ObjectStream 이란?
- ObjectOutputStream 과 ObejctInputStream은 각각 객체를 직렬화, 역직렬화하는 메소드를 제공하는 스트림이다.
- 객체 스트림은 프로그램 메모리상에 존재하는 객체를 직접 입출력해 줄 수 있는 스트림으로 현재 상태를 보존하기 위한 영속성을 지원할 수 있다.
- 자바에서 객체 안에 저장되어 있는 내용을 파일로 저장하거나 네트워크를 통하여 다른 곳으로 전송하려면 객체를 바이트 형태로 일일이 분해해야 한다. 이를 위하여 객체를 직접 입출력 할 수 있도록 해주는 객체 스트림이다.
즉 ObejctStream을 사용하기 위해서 객체가 직렬화(Serialization) 가 되어 있어야 한다는 것이다.
사용 예시)
1) ObjectOutputStreamEx.java
public class ObjectOutputStreamEx {
public static void main(String[] args) {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("c:\\iotest\\obj.txt"));
Data data = new Data(1, "choi", "abc@naver.com");
oos.writeObject(data);
System.out.println("입력 완료");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2) ObjectInputStreamEx.java
//역직렬화해서 파일에서 읽어오기
public class ObjectInputStreamEx {
public static void main(String[] args) {
ObjectInputStream ois = null;
try {
// 파일에 저장된 객체를 읽어들이기 위해 ObjectInputStream 객체 생성
ois = new ObjectInputStream(new FileInputStream("c:\\iotest\\obj.txt"));
// ObjectInputStream 은 스트림으로 부터 읽어들인 직렬화된 객체를 역직렬화해서 객체를 생성할 수 있다.
// 역직렬화할때 필요한 클래스 파일을 찾지 못할 경우
// ClassNotFoundException 을 발생시킴.
Data data = (Data) ois.readObject();
System.out.println("번호 : " + data.getNo());
System.out.println("이름 : " + data.getName());
System.out.println("메일 : " + data.getMail());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (ois != null) {
ois.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Serizable 된 Data 객체를 obj.txt 파일에다가 ObjectOutputStream을 이용해 저장하고 ObjectInputStream을 사용해 역직렬화하여 Data객체를 복구 해오는 것을 볼 수 있습니다.
# 참고자료
woowabros.github.io/experience/2017/10/17/java-serialize.html
docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html
docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html
'Backend > Java' 카테고리의 다른 글
[JAVA] ObjectStream을 이용한 Socket 통신 (0) | 2021.01.14 |
---|---|
[JAVA] 간단한 고객관리프로그램 (0) | 2021.01.04 |
[JAVA] 계산기 만들기 (0) | 2020.12.30 |
[JAVA] String, StringBuffer, StringBuilder 의 차이점 (0) | 2020.12.18 |
[JAVA] 추상클래스(Abstract Class) (0) | 2020.12.17 |