♣Computer Science♣/JAVA

직렬화(serializable)

클로버,, 2010. 8. 12. 14:32
* 자바에서 데이터를 표현하는 가장 중요한 도구는 인스턴스이다. 스트림을 통해서 기본 데이터들 뿐만 아니라,
인스턴스를 통째로 입출력 할 수 있어야 의미 있는 프로그램 구현이 한결 수월해진다.

* 인스턴스의 입출력에 사용되는 클래스 : ObjectInputStream, ObjectOutputStream
  인스턴스의 저장을 위해서 호출해야 할 메소드 public final void writeObject(Object obj) throws IOException
  인스턴스의 복원을 위해서 호출해야 할 메소드 public final Object readObject() throws IOException

인스턴스가 파일에 저장되는 과정을 직렬화, 파일로부터 인스턴스가 복원되는 과정을 가리켜 역직렬화 라고 한다.


import java.io.*;

class ByteFileCopy implements Serializable
{
	int xPos;
	int yPos;
	double rad;
	
	public ByteFileCopy(int x, int y, double r)
	{
		xPos=x;
		yPos=y;
		rad=r;
	}
	
	public void showCircleInfo()
	{
		System.out.printf("[%d, %d]\n", xPos, yPos);
		System.out.println("rad: " +rad);
	}
	public static void main(String[] args) throws IOException, ClassNotFoundException
	{
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("object.ser"));
		
		out.writeObject(new ByteFileCopy(1, 1, 2.4));
		out.writeObject(new ByteFileCopy(2, 2, 4.8));
		out.writeObject(new String("String implements Seri"));
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("object.ser"));
		
		ByteFileCopy b1= (ByteFileCopy)in.readObject();
		ByteFileCopy b2= (ByteFileCopy)in.readObject();
		
		String message = (String)in.readObject();
		in.close();
		
		b1.showCircleInfo();
		b2.showCircleInfo();
		System.out.println(message);
	}

}


 인스턴스의 입출력은 리소스의 소모가 많은 작업이다. 때문에 과도한 직렬화는 성능에 영향을 줄 수 있다. 하지만 연속적으로
입출력이 발생하는 상황이 아니라면, 시스템에 영향을 주지 않는 상황이라면, 직렬화의 적절한 활용은 다양한 상황에서
프로그래머의 수고를 덜어주기도 한다.
 
직렬화 개념에 대해서 좀 더 자세히 알고 싶어 검색하다가 IBM DeveloperWorks 사이트에서 Java Object Serialization에
대해 정리해 놓은 컨텐츠를 찾았다. (링크: http://www.ibm.com/developerworks/kr/library/j-5things1/index.html)
정리하면,,
 

 기본적으로 직렬화라는 개념은 오브젝트 그래프를 "고정"하고 디스크 또는 네트워크로 이동한 다음 그래프를 사용 가능한 Java 오브젝트로 "되돌리는" 것이다. 이 모든 작업은 ObjectInputStream/ObjectOutputStream 클래스, 신뢰성 높은 메타데이터 및 클래스에 Serializable 표시자 인터페이스를 태그로 지정하여 이 프로세스를 "선택"한 프로그래머의 의지로 인해 마술처럼 발생한다.

 

serialization의 특징 중 하나는 안전하지 않다는 것인데,, 직렬화된 2진 스트림의 컨텐츠를 콘솔에서 보면 클래스의 형태와 내용을 충분히 파악할 수 있다.  다행스럽게도, Serialization에는 직렬화 이전과 해제 이후에 직렬화 프로세스를 "선택"해서 필드 데이터에 대한 보안 설정(또는 감추기)을 수행할 수 있는 기능이 있다. Serializable 오브젝트의 writeObject 메소드를 사용하여 이를 수행할 수 있다.


 직렬화의 대상에서 제외시키고 싶은 인스턴스 변수가 있다면 transient로 선언한다.  



 

transient String secreInfo;
transient int secretNum;
즉, transient로 선언된 변수들은 복원의 과정에서 별도의 초기화가 이루어지지 않는다.