티스토리 뷰

[직렬화]

: 객체를 스트림(=연속적인 데이터)으로 만드는 것

  객체의 모든 인스턴스 변수들의 값을 일렬로 나열하는 것

  => 객체의 내용을 저장했다가 꺼내 쓸 수 있도록 하기 위함

 

객체를 저장하기 위해서는 객체를 직렬화해야 한다.

-> 객체를 저장하는 것과 객체를 직렬화하는 것은 같은 의미로 볼 수 있다.

 

객체를 저장하기 위한 파일의 확장자명은 주로 .ser를 사용한다.

 

 

직렬화

: ObjectOutputStream 객체의 writeObject() 메소드를 이용

역직렬화

: ObjectInputStream 객체의 readObject() 메소드를 이용,

  이 때 반환타입은 Object이므로 본래 객체 타입으로 형변환 해주어야 함

 

자동 직렬화/역직렬화 메소드

: defaultWriteObject() / defaultReadObject()

 

 

ex)

package StreamEx;

import java.io.*;

public class Serialization implements Serializable {
	String id;
	String pw;
	
	public static void main(String[] args) throws Exception{
    
		// 직렬화
		FileOutputStream fo = new FileOutputStream("obj.ser");
		ObjectOutputStream out = new ObjectOutputStream(fo);
		
		out.writeObject(new AAA());	
		
		// 역직렬화
		FileInputStream fin = new FileInputStream("obj.ser");
		ObjectInputStream in = new ObjectInputStream(fin);
		
		AAA aaa = (AAA)in.readObject();	// 형 변환 해주어야 함
        
	}
}

class AAA {
	
}

 

 

직렬화 시 모든 내부 값들이 저장이 되는데, 암호와 같은 보안 정보는 저장되어서는 안됨

-> 'transient' 키워드를 붙여주면 직렬화를 해도 값이 저장되지 않음

 

직렬화해야 하는 객체가 많은 경우

-> 모든 객체에 하나하나 writeObject() 메소드를 사용하는 것보다 arrayList에 모두 add를 해놓고 한번에 arrayList에 writeObject() 메소드를 사용하는 것이 효율적!

 

ex)

package StreamEx;

import java.io.*;

class PersonInfo implements Serializable {
	String id;
	transient String pw;	// 'transient' 키워드를 사용하면 직렬화 시 저장되지 않음
	String name;
	
	public PersonInfo() {
		this("id0000", "0000", "체봄");
	}
	public PersonInfo(String id, String pw, String name) {
		this.id = id;
		this.pw = pw;
		this.name = name;
	}
	
	public String toString() {
		return "<"+id+", "+pw+", "+name+">";
	}
}
	
public class SavePersonInfo {
	public static void main(String[] args) throws Exception {
		String fname = "obj.ser";
        
        // 직렬화 과정
		FileOutputStream fo = new FileOutputStream(fname);
		BufferedOutputStream bo = new BufferedOutputStream(fo);
		ObjectOutputStream out = new ObjectOutputStream(bo);
		
		PersonInfo p1 = new PersonInfo("id1234", "1111", "체리");
		PersonInfo p2 = new PersonInfo("id0323", "2222", "마루");
		PersonInfo p3 = new PersonInfo("id0500", "3333", "호두");
		
        // 일일이 저장 시 번거로움
//		out.writeObject(p1);
//		out.writeObject(p2);
//		out.writeObject(p3);
		
		// 객체들을 모두 ArrayList에 담음
		ArrayList al = new ArrayList();	
		al.add(p1); 
		al.add(p2);
		al.add(p3);
		
		out.writeObject(al);	// 한 번에 직렬화
        
		out.close();
		bo.close();
		fo.close();	
        
        
        
        // 역직렬화 과정
		FileInputStream fi = new FileInputStream(fname);
		BufferedInputStream bi = new BufferedInputStream(fi);
		ObjectInputStream in = new ObjectInputStream(bi);
		
		// ArrayList 객체로 직렬화했으므로 ArrayList타입 변수에 역직렬화
		ArrayList list = (ArrayList)in.readObject();
		
		System.out.println(list);	// 저장된 정보 출력
		
		
		in.close();
		bi.close();
		fi.close();  
	}
}

실행 결과>>

[<id1234, null, 체리>, <id0323, null, 마루>, <id0500, null, 호두>]


 

역직렬화 과정에서 ArrayList 객체명 list를 출력하면, ArrayList 내부에 저장된 PersonInfo 객체명 p1, p2, p3이 출력된다.

PersonInfo 클래스에서 toString() 메소드를 오버라이딩 했기 때문에 각 객체에서 "<아이디, 패스워드, 이름>" 이 출력된다.

이 때, 패스워드는 저장되어서는 안되는 보안 정보이므로 transient 키워드를 붙여놓았기 때문에 패스워드는 저장되지 않아서 출력 시 null로 나온다.

 

반응형

'Java, JavaScript' 카테고리의 다른 글

[Java] 선택 정렬(Selection Sort)  (0) 2019.08.16
[Java] 삽입 정렬(Insertion Sort)  (0) 2019.08.16
[Java] 병합 정렬(Merge Sort)  (0) 2019.07.31
[Java] 문자 스트림  (0) 2019.07.26
[Java] File 클래스  (0) 2019.07.24

댓글