직렬화 역직렬화 (집공부)
자바는 메모리에 생성된 객체를 파일 또는 네트워크로 출력할 수가 있다.
객체는 문자가 아니기 때문에 바이트 기반 스트림으로 출력해야 한다.
객체를 출력하기 위해 객체의 데이터(필드값)를 일렬로 늘어선 연속적인 바이트로 변경해야 하는데, 이것을 객체 직렬화 라고한다.
1. ObjectInputStream , ObjectOutputStream
자바는 객체를 입출력할 수 있는 두 개의 보조 스트림인 ObjectInputStream과 ObjectOutputStream 을 제공한다.
1-1) ObjectOutputStream
-> 바이트 출력 스트림과 연결되어 객체를 직렬화 하는 역할을 하고,
-> 객체를 직렬화 하기 위해서는 writeObject() 메소드를 사용한다.
ex)
oos.writeObject(객체);
1-2) ObjectInputStream
-> 바이트 입력 스트림과 연결되어 객체를 역직렬화 하는 역할을 한다.
-> readObject() 메소드는 입력 스트림에서 읽은 바이트를 역직렬화 해서 객체로 생성한다.
-> readObject() 메소드의 리턴 타입은 Object 타입이기 때문에 객체 원래의 타입으로 변환해야한다.
ex)
객체타입 변수 = (객체타입) ois.readObject();
합친ex)
ObjectInputStream ois = new ObjectInputStream(바이트스트림);
ObjectOutputStream oos = new ObjectOutputStream(바이트출력스트림);
=====================================================================================
1> 직렬화가 가능한 클래스(Serializable)
-> 자바는 Serializable 인터페이스를 구현한 클래스만 직렬화할 수 있도록 제한하고 있다.
ex)
public class XXX implements Serializable{}
----------------------------------------------------------------------------------------------------------------
소스
========================================================================================
설명
먼저 SerializableWriter 클래스를 실행하면 ClassA 객체를 직렬화해서 Object.dat 파일에 저장한다. 그리고 나서 serializablereader클래스를
실행하면 Object.dat파일에 저장된 데이터를 읽고 ClassA 객체로 역직렬화한다. 실행 결과를 보면 field1과 field2는 값이 복원되는 것을 알 수 있으나
static필드인 field3과 transient 필드인 field4는 값이 복원되지 않는다. Object.dat 파일에는 field1과 field2의 데이터만 저장되어 있기 떄문이다.
========================================================================================
package jongkyu.example;
import java.io.Serializable;
public class ClassA implements Serializable {//직렬화가 가능한 클래스
int field1; //직렬화에 포함
ClassB field2 = new ClassB(); //직렬화에 포함
static int field3; //직렬화에서 제외
transient int field4; //직렬화에서 제외
}
//직렬화가 가능한 클래스
--------------------------------------------------------------------------------------
package jongkyu.example;
import java.io.Serializable;
public class ClassB implements Serializable {//직렬화가 가능한 클래스
int field1;//직렬화에 포함
}//직렬화가 가능한 클래스
package jongkyu.example;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializableWriter {
//직렬화해서 파일에 저장
public void main() throws Exception {
FileOutputStream fos = new FileOutputStream("C:\\Temp\\Object.dat");
//FileOutputStream을 써서 저경로에 파일을 저장한다.
ObjectOutputStream oos = new ObjectOutputStream(fos);
//보조스트림을 추가시켜줘서 더 원활하게 가도록 하였다.
ClassA classA = new ClassA();//클래스 A형객체를 classA로만들었다.
classA.field1=1;
classA.field2.field1=2;
classA.field3=3;
classA.field4=4;
oos.writeObject(classA);
oos.flush(); oos.close(); fos.close();
}
}
//직렬화해서 파일에 저장
-----------------------------------------------------------------------------
package jongkyu.run;
import jongkyu.example.SerializableReader;
import jongkyu.example.SerializableWriter;
public class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
SerializableReader sr = new SerializableReader();//직렬화해서 파일에 저장하는 역할
SerializableWriter sw = new SerializableWriter();//역직렬화해서 복원된 필드 조사
try {
sr.main();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}