[JAVA] Day 18 - 직렬화 / 역직렬화

sue·2023년 12월 10일

📒국비학원 [JAVA]

목록 보기
17/20
post-thumbnail

직렬화

  • 데이터를 파일에 저장하는 방법 중 하나
  • 객체를 직렬화해 바이트 스트림으로 변환시켜 파일이나 네트워크를 통해 전송되거나 저장됨.
  • implements Serializable로 구현 - 메서드 없음 x => 해당 클래스로 직렬화시킴

    장점 :

    객체 내용의 입출력형식에 구애받지 않음 / 프로그램이 종료되고 재실행 할때 - 객체를 파일에 저장함으로써 나중에 다시 불러와서 쓸 수 있는 영속성을 가질 수 있음

    why? 이미 구현받은 인터페이스가 있으므로 -> 아래에서 map 먼저 구현 후 default값으로 serializable이 구현되어있어서 안써도 괜찮음

역직렬화

  • 직렬화된 바이트 스트림을 읽어와서 다시 원래 객체로 변환

사용처

네트워크 통신 : 클라이언트 + 서버간의 통신에서 데이터를 직렬화해서 네트워크를 통해 데이터 전송 -> 서버에서는 그 데이터를 역직렬화해서 작업처리함

DB저장: 객체나 데이터 구조를 저장하려면 직렬화해서 저장해야 함. 이후 필요한 데이터는 역직렬화하여 다시 사용가능


📌 Note Code


  • Hashable : Map[i]의 클래스 / 키 - 값 / 키값을 인덱스로 사용하여 배열에 키와 값 저장 => 키로 값을 빠르게 검색할 수 있음

  • FileOutputStream (fos :직렬화 못함) -> 누군가 감싸줘야함 : ObjectOutputStream (직렬화해서 내보냄)

  • FileOutputStream : 파일저장

  • oos.writeObject(h); : (직렬화)ObjectOutputStream에 있는 h(hashtable 맵)를 직렬화하고 , 그 결과를 출력 스트림에 씀



13. ⭐ 직렬화 (ObjectOutputStream)

Test13

💻 입력


import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;

//직렬화
public class Test13 {

	public static void main(String[] args) throws Exception {

		//직렬화코드
		Hashtable<String, String> h = new Hashtable<String, String>();
				
		h.put("1","배수지");
		h.put("2","이이담");
		h.put("3","유인나");
		
		//파일저장 : fileoutputStream (직렬화할 수 있는 능력은 없음)
		//직렬화 된 fos데이터는 내보낼 수 없기때문에(=ObjectOutputStream : 직렬화된 데이터 내보낼 수 있음)  - Stream (fos를 감싸고있음)  
		
		FileOutputStream fos = new FileOutputStream("c:\\doc\\out5.txt");
		
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		
		//겉에있는 얘 (↑ oos) 내보냄
		oos.writeObject(h); //맵을 내보낼거임
		oos.close();
		fos.close();
		
		System.out.println("파일로 내보냈습니다");
	}
}


💡 **출력**
파일로 내보냈습니다



📌 Note Code


  • FileInputStream : 파일 읽어냄
  • Hashtable<String, String> h = (Hashtable<String, String>) ois.readObject();

ois에 있는 object를 읽어내라 근데 object가 Hashtable인 클래스보다 더 큰 부모니까 downcast해야함

  • Map = 순서보장 x
    : iterator로 탐색( Set 빌려씀 - keySet().iterator )



14. ⭐ 역직렬화 (ObjectInputStream)

Test14

💻 입력


public class Test14 {

	public static void main(String[] args) throws Exception {

		//역직렬화
		FileInputStream fis = new FileInputStream("c:\\doc\\out5.txt");
		
		ObjectInputStream ois = new ObjectInputStream(fis);//감싸주기
		
		Hashtable<String, String> h = (Hashtable<String, String>) ois.readObject(); //파일 (c:\\doc\\out5.txt) 안에는 map이 들어있음 -> map으로 받아줘야함
		//다운캐스팅 
		
		
		//Map 순서보장 x
		Iterator<String> it = h.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next();
			String value = h.get(key);
			System.out.println(key + " : "+value);
		}
	}
}


💡 **출력**
//13직렬화로 내용 저장된거 꺼냄
3 : 유인나
2 : 이이담
1 : 배수지



📌 Note Code




15. 직렬화 / try-catch문을 이용한 파일과 메모리간의 입출력

Test15

💻 입력 - DataMain


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class DataMain {

	public static void main(String[] args) {

		try {

			FileOutputStream fos = new FileOutputStream("c:\\doc\\data.txt");

			ObjectOutputStream oos = new ObjectOutputStream(fos); //데이터 넣는 명령어 : oos.writeObject();
			
			oos.writeObject(new DataVO("배수지", 100)); //lists.add(vo) 와 비슷한 느낌 / VO가 클래스 -  오버로딩된 생성자에서 값을 초기화하기때문에  데이터 넣을때 그 안에 바로 객체생성하겠다.
			oos.writeObject(new DataVO("이이담", 200));
			oos.writeObject(new DataVO("유인나", 300));
			oos.writeObject(new DataVO("박신혜", 400));
			oos.writeObject(new DataVO("고문영", 500));
			//해당내용들이 "c:\\doc\\data에 저장됨
			
			oos.close();
			fos.close(); //직렬화 끝
			
			System.out.println("데이터 저장완료!!");
			
			
			//역직렬화 --------------------------------------- (꺼내는)
			
			FileInputStream fis = new FileInputStream("c:\\doc\\data.txt");
			
			ObjectInputStream ois = new ObjectInputStream(fis);
			
			DataVO ob = null;
			
			try {
				
				while(true) { //데이터 몇개꺼낼지 몰라
					
					ob = (DataVO)ois.readObject(); //ois.readObject = 하나꺼낼거야
					//다운캐스트 
					
					if(ob==null) { //마지막 하나 꺼냈는데 없을 때 
						break; 
					}
					
					System.out.println(ob.toString());
				}
				
				
				
				
			} catch (Exception e) {
				//System.out.println(e.toString()); => 안 쓴 이유 : eof 마지막 파일이다
			}
			
			ois.close();
			fis.close();
	
			
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}
}


💻 입력 - DataVO


import java.io.Serializable;


// implements Serializable  직렬화 줌
public class DataVO implements Serializable {

	private static final long serialVersionUID = 1L;
	
	private String name;
	private int score;
	
	public DataVO(String name,int score) { //오버로딩된 생성자를 통해 값초기화 -> setter getter 필요없음
		this.name = name;
		this.score = score;
		
	}
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	
	@Override
	public String toString() {
		return name + " : " +score;
	}
}


💡 **출력**
데이터 저장완료!!
배수지 : 100
이이담 : 200
유인나 : 300
박신혜 : 400
고문영 : 500


0개의 댓글