다연이네

[days26] 직렬화(Serialization) - ObjectInputStream/ObjectOutputStream 본문

Java

[days26] 직렬화(Serialization) - ObjectInputStream/ObjectOutputStream

 다연  2020. 10. 26. 22:47
반응형

직렬화

 객체를 데이터 스트림으로 만드는 것 (객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 것)
<->역직렬화 - 스트림으로부터 데이터를 읽어서 객체를 만드는 것

 

 ObjectInputStream/ObjectOutputStream - 객체 직렬화/역직렬화 알아서 해 줌

 

1. 메소드를 통해 파일 생성, 콘솔에 출력

package days26;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class Ex01 {

	public static void main(String[] args) {
		
		Member m1= new Member("홍길동", 1000, true); //값 아무거나
			
		String fileName = ".\\src\\days26\\member.dat"; 
		m1.writeExternal(fileName);
		//m1을 fileName에 쓰기작업하는 함수 만든 것
		
		System.out.println("------------------"); //쓰기작업 후
		Member m2= new Member();
		 m2 = m1.readExternal(fileName); 
		
		 System.out.println(m2.getName());
		 System.out.println(m2.getType());
		 System.out.println(m2.isGender()); 
         //getGender가 없다 : boolean형으로 하면 isXXX
		
		

	}//main

}//class

//객체를 파일로 쓰기/읽기
class Member{
	private String name;
	private long type;
	private boolean gender;
	
	public Member() {	}

	public Member readExternal(String fileName) {
		//역직렬화같이 (파일로부터 멤버객체를 만들어 돌려줌)
		Member m = null;
		try(
				FileReader fr = new FileReader(fileName);
				BufferedReader br = new BufferedReader(fr);
				) {
			
			String name = br.readLine();
			int type = Integer.parseInt(br.readLine());
			boolean gender = Boolean.parseBoolean(br.readLine());
			
			m = new Member(name, type, gender);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return m; 
	}

	//m1.writeExternal(fileName)
	//m1 객체를 fileName 파일로 저장하는 메소드
	public void writeExternal(String fileName) {
		try(
				FileWriter fw = new FileWriter(fileName);
				BufferedWriter bw = new BufferedWriter(fw);
				) {
			bw.write(this.name+"\n");
			bw.write(this.type+"\n");
			bw.write(this.gender+"\n"); //세 라인으로 하나의 객체가 들어간 것
			
			System.out.println("> 객체 저장 완료 <");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Member(String name, long type, boolean gender) {
		super();
		this.name = name;
		this.type = type;
		this.gender = gender;
	}

	public String getName() {
		return name;
	}

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

	public long getType() {
		return type;
	}

	public void setType(long type) {
		this.type = type;
	}

	public boolean isGender() {
		return gender;
	}

	public void setGender(boolean gender) {
		this.gender = gender;
	}
	

}

 

2. ObjectInputStream/ObjectOutputStream 사용

package days26;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Ex01_02 {

	public static void main(String[] args) {
		
		Student s1 = new Student("홍길동", 89, 77, 98, 264, 88, true);
		
		
		String fileName =  ".\\src\\days26\\Student.dat";
		
		try(
				FileOutputStream out= new FileOutputStream(fileName);
				ObjectOutputStream oos = new ObjectOutputStream(out); // 보조스트림이구나 
							
				){
			oos.writeObject(s1); //자동으로 직렬화 -> 파일 저장
		}  catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println("---------");
		
		//역직렬화
		
		try (
				FileInputStream in = new FileInputStream(fileName);
				ObjectInputStream ois = new ObjectInputStream(in);
				){
			Student s2 = (Student)ois.readObject(); // 자동으로 역직렬화시켜서 객체로 반환
			//오브젝트로 돌려주기 때문에  다운캐스팅 필요
			
			
			System.out.println(s2.getName());
			System.out.println(s2.getKor());
			System.out.println(s2.getTot());
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		
		System.out.println("=END=");
		
		
	

	}//main

}//class

class Student implements Serializable{ //직렬화가 가능한 클래스를 만드려면 반드시 Serializable을 implement 해줘야 함
	
	private static final long serialVersionUID = -6323724618713312921L; //객체에 대한 고유한 값
	//이게 같아야 같은 클래스( 역직렬화시 체크하는 것)
	
	private String name;
	private int kor, eng, mat;
	//총점 - 직렬화할때 대상에서 제외시키고 싶다
	//1) static 필드(클래스 변수)는 직렬화 대상 제외
	//2) transient 키워드를 붙히면 직렬화 대상에서 제외
	private transient int tot;
	private double avg;
	private boolean gender;
	
	
	
	public Student() {
		super();
	}

	public Student(String name, int kor, int eng, int mat, int tot, double avg, boolean gender) {
		super();
		this.name = name;
		this.kor = kor;
		this.eng = eng;
		this.mat = mat;
		this.tot = tot;
		this.avg = avg;
		this.gender = gender;
	}

	public String getName() {
		return name;
	}

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

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getMat() {
		return mat;
	}

	public void setMat(int mat) {
		this.mat = mat;
	}

	public int getTot() {
		return tot;
	}

	public void setTot(int tot) {
		this.tot = tot;
	}

	public double getAvg() {
		return avg;
	}

	public void setAvg(double avg) {
		this.avg = avg;
	}

	public boolean isGender() {
		return gender;
	}

	public void setGender(boolean gender) {
		this.gender = gender;
	}
	
	
	
	
	
}

* 직렬화할때 대상에서 제외시키는 방법
1) static 필드(클래스 변수)는 직렬화 대상 제외
2) transient 키워드를 붙히면 직렬화 대상에서 제외 - private transient int tot;

 

 

- 부모클래스가 직렬화가 가능하다면 자식클래스도 자동으로 직렬화가 가능하다.

class Parent implements Serializable{
	
}

class Child extends Parent{
	
}

- Child 클래스가 직렬화가 가능할지라도 부모의 필드(p)는 직렬화 대상이 아니다.

만약에 부모의 필드(p)도 직렬화 대상에 포함시키고자 한다면 직접 메소드를 구현하면 된다.

class Parent{
	public String p;
}

class Child extends Parent implements Serializable{
	public String c;
	private void writeObject(ObjectOutputStream out) throws IOException{
		out.writeUTF(p);
		out.defaultWriteObject();
	}
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
	 p = in.readUTF();
	 in.defaultReadObject();
	}
}
반응형

'Java' 카테고리의 다른 글

[days26] 스레드 예제  (0) 2020.10.26
[days26] 스레드(Thread)  (0) 2020.10.26
[days25] DataOutputStream, DataInputStream  (0) 2020.10.25
[days25] RandomAccessFile  (0) 2020.10.25
[days25] 메모리스트림 - StringReader / StringWriter  (0) 2020.10.25
Comments