양아무개 2020. 4. 29. 19:00

 

# I/O

앞서 사용했던 InputStream/ OutputStream은 byte단위로 처리되기 때문에 한글이 깨지게 된다. 

문자만 처리하는 IO Stream도 있다. 

Reader/ Writer이다. 

 

문자열로 보낼 경우엔 보낼 데이터들을 클래스 객체화를 해서 묶는다. 

그런 후 객체들을 byte 단위로 잘게 쪼개어서 buffer로 보낸다. 

이렇게 byte 단위로 쪼개는 과정을 마샬링이라고 한다. 

마샬링을 수행하는 인터페이스는 Serializable 이다. 

Serializable은 보낼 값들을 쪼개고 뭉쳐준다. 

 

이렇게 buffer로 보낸 값들은 다시 최종목적지인 파일로가 다시 묶이게 된다. 

이렇게 쪼개어진 것을 다시 묶는 것은 언마샬링이라고 한다. 

 

아래의 예시코드를 보자.

먼저 한 사람 분량의 정보가 들어있는 PersonDTO 클래스이다. 

본 클래스의 정보들을 쪼개고 뭉쳐주는 (Serializable) 작업을 해줄 것이기 때문에 PersonDTO 클래스에 Serializable을 걸어준다. 

Serializable은 한 번 쓰고 말 것이기 때문에 클래스에 바로 import를 걸어준다. 

class PersonDTO implements java.io.Serializable{
	private static final long serialVersionUID = 1L;
	private String name; 
	private int age; 
	private double height;
	
    public PersonDTO(String name, int age, double height){
		this.name = name;
		this.age = age;
		this.height = height;
	}
   	 //getter
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
	public double getHeight(){
		return height;
	}
}

   serialVersionUID는 직렬화에 사용되는 고유 아이디이다. 선언하지 않을 시엔 JVM에서 디폴트로 자동 생성이 된다. 

위의 ID는 직렬화와 역직렬화시 사용된 클래스의 serialVersionUID가 같은지 확인해 같은 클래스인지 식별하는 식별자 역할을 한다. 지금은 역직렬화를 하지 않을 것이기 때문에 잠시 넘어간다. 

한 사람의 정보로는 이름, 나이, 키가 있고 생성자로 정보를 받고 getter 메서드를 따로 생성해주었다. 


다음은 ObjectMain 클래스에서 정보를 받는다. 

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

class ObjectMain{
	public static void main(String[] args) throws ClassNotFoundException, IOException{
		PersonDTO dto = new PersonDTO("양아무개", 25, 183.3);

만약 PersonDTO 에 Serializable을 해주지 않으면 데이터를 보낼 수 조차 없다. 

 

먼저 result2.txt 파일에 데이터를 보낸다. 

이전에는 FileOutputStreamDataOutputStream를 통해 데이터를 하나씩 하나씩 보냈지만, 

이번에는 ObjectOutputStream 로 객체 자체로 묶어준 데이터를 한꺼번에 보낸다. 

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("result2.txt"));
oos.writeObject(dto); 
oos.close();

 dto 객체를 통해 데이터가 한 번에 나가게 되었다. 

 

이제 result2.txt에 있는 데이터들을 출력해본다. 

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("result2.txt"));
PersonDTO dto2 = (PersonDTO)ois.readObject();

result2.txt에 있는 데이터들을 다시 dto를 넣는 과정을 통해 쪼갠 것들을 다시 뭉쳐놓는다. 

데이터들을 꺼내줄 때는 object로 꺼내진다. 그래서 readObject() 이다.

하지만 지금 받고자 하는 타입은 PersonDTO이므로 형변환을 해준다. 

		System.out.println("이름 = " + dto2.getName());
		System.out.println("나이 = " + dto2.getAge());
		System.out.println("키 = " + dto2.getHeight());
		
	}
}