JAVA_12_입출력 2

송지윤·2024년 2월 23일

Java

목록 보기
21/22

직렬화와 역직렬화

직렬화(Serialization)

Serializable 인터페이스를 implements하여 구현
객체 직렬화 시 private 필드를 포함한 모든 필드를 바이트로 변환하지만 transient키워드를 사용한 필드는 직렬화에서 제외

역직렬화(Deserialization)

직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스 사용
단, 클래스 이름이 같더라도 클래스 내용이 변경된 경우 역직렬화 실패

serialVersionUID 필드

직렬화한 클래스와 같은 클래스임을 알려주는 식별자 역할로 컴파일 시 JVM이 자동으로
serialViersionUID 정적 필드를 추가해줘 별로도 작성하지 않아도 오류는 나지 않지만
자동 생성 시 역직렬화에서 예상하지 못한 InvalidClassException을 유발할 수 있어 명시 권장

private static final long serialVersionUID = -6423919775137290062L;

ObjectInputStream / ObjectOutputStream
Java 객체(Instance == Object)를 입/출력 할 때
사용하는 바이트 기반 "보조" 스트림
(보조 스트림은 단독 사용 불가능)

직렬화(Serializable)
객체를 직렬(직선) 형태로 변환

직렬화 한 Member 클래스

직렬화 방법 -> Serializable 인터페이스를 상속 받으면 끝

Serializable 인터페이스
추상 메서드가 하나도 없는 인터페이스
상속만 받아도 입/출력 시 직렬화가 가능하다는 의미(표시)만 제공
-> 마커 인터페이스

import java.io.Serializable;

public class Member implements Serializable {
	// OutputStream 으로 내보낼 객체
	
	// 필드
	private String id;
	private String pw;
	private String name;
	private int age;
	
	public Member() {} // 기본 생성자

	public Member(String id, String pw, String name, int age) {
		this.id = id;
		this.pw = pw;
		this.name = name;
		this.age = age;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPw() {
		return pw;
	}

	public void setPw(String pw) {
		this.pw = pw;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Member [id=" + id + ", pw=" + pw + ", name=" + name + ", age=" + age + "]";
	}
	
}

객체를 외부 파일로 출력

	public void objectOutput() {
		
		// 기반 스트림 필요
		FileOutputStream fos = null;
		ObjectOutputStream oos = null;
		// 스트림 참조 변수 선언 아직 객체 만들기 전
		
		try {
			// c 드라이브 Member.dat 경로에 가서 찾고 없으면 만들어줌
			fos = new FileOutputStream("/io_test/20240222/Member.dat");
			// .dat 확장자 : data 를 담고 있는 파일을 나타내는 확장자
			// 객체 만들어서 내보내려고 data 확장자 만듦 객체들 내보낼 때 쓰는 확장자
			
			oos = new ObjectOutputStream(fos); // 객체 보조 스트림 생성
			// try catch 문 안에 작성 예외 발생 때문에
			
			// Member 객체 하나 생성
			Member member = new Member("member01", "pass01", "김회원", 30);
			
			// ObjectOutStream을 이용해서 Member 객체를 출력하기
			oos.writeObject(member); // 객체를 쓰는 거여서 writeObject 사용
			// 객체 출력하는 구문
			
			System.out.println("회원 출력 완료");
			
			// java.io.NotSerializableException: edu.kh.io.pack3.model.dto.Member
			// 직렬화가 되지 않았다. : 객체에 대해서
			// 멤버 클래스 직렬화 해줘야함
				
		} catch(Exception e) { // 모든 예외 Exception
			e.printStackTrace();
		} finally {
			// Stream 꼭 문 닫아야함
			// 보조 스트림 닫으면 기반 스트림도 닫힘
			try {
				// 그냥 닫으면 또 예외 발생해서 try catch 안에 작성
				if(oos != null) oos.close();
			} catch(IOException e) {
				e.printStackTrace();
			}
			
		}
	
	}

0개의 댓글