직렬화란 자바의 객체를 네트워크 상에서 주고받게 하기 위하여 메모리에 저장된 객체를 바이너리 형식으로 변환하는 것을 뜻합니다. 역직렬화는 당연히 반대의 과정입니다.

이렇게 변환된 직렬화된 객체는 하드디스크에 저장하거나 네트워크 상으로 전송하여 다른 컴퓨터에서 사용하도록 할 수 있습니다.

직렬화를 하려면 대상 클래스가 Serializable 인터페이스를 구현해야 합니다. 참고로 ArrayList를 비롯한 몇몇 자바 클래스에서는 이미 Serializable 구현이 되어 있습니다. 객체 단위보다는 List 단위로 객체 직렬화-역직렬화를 하는 것이 효율적일 것입니다.

객체 직렬화-역직렬화 시 serialVersionUID가 서로 맞아야 제대로 작동합니다. 일반적으로 따로 선언하지 않아도 자바 내부에서 자동으로 버전을 생성하지만 이 경우 클래스의 잦은 내용 변경 시 문제가 발생하게 됩니다.

자바에서는 serialVersionUID를 사용자가 임의의 값으로 설정하여 내부에서 관리하는것을 추천한다고 합니다. 이클립스의 기능을 이용하면 기본 아이디를 만들거나 임의로 생성된 아이디를 사용할 수 있습니다.

예제는 자바의 List를 사용해서 게시판을 만들어보는 것입니다. 애초에 그냥 자바에서 만든 List라면 해당 객체가 프로그램이 실행되었을 때 만들어지며 프로그램이 꺼지면 메모리에서 사라지고 안에 들어있던 내용은 영원히 다시 볼 수 없을 것입니다.

그러나 직렬화를 사용하여 글이 작성되면 List의 내용을 하드디스크에 저장하고 프로그램을 껐다 다시 실행해도 하드디스크에 있는 직렬화된 파일을 읽어 List의 내용을 복구할 수 있습니다.


package blog.seri;
import java.io.Serializable;
// 직렬화하려는 클래스는 반드시 Serializable을 implements 해야 한다.
public class Article implements Serializable{
/**
* 이클립스에서 Adds a generated serial version ID 기능을 이용하면
* 자동으로 시리얼 아이디를 생성해준다.
*/
private static final long serialVersionUID = -83252522547L;
public int seq;
public String writer, message;
public Article(int seq, String writer, String message) {
super();
this.seq = seq;
this.writer = writer;
this.message = message;
}
@Override
public String toString() {
return seq + "\t" + writer + "\t" + message;
}
}

view raw

Article.java

hosted with ❤ by GitHub


package blog.seri;
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.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Board {
static List<Article> list = new ArrayList<>();
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 직렬화 입력받기: 파일로부터 직렬화된 내용을 읽어 객체로 변환시킨 뒤
// 메모리에 적재시킨다.
try {
readFromFile();
} catch(FileNotFoundException e) {}
Scanner s = new Scanner(System.in);
while(true) {
prompt(s);
}
}
private static void prompt(Scanner s) throws FileNotFoundException, IOException {
displayBoard();
System.out.print(">> ");
String command = s.nextLine();
if(command.equalsIgnoreCase("w") || command.equalsIgnoreCase("write")) {
write(s);
} else if (command.equalsIgnoreCase("x") || command.equalsIgnoreCase("exit")) {
System.exit(0);
}
}
private static void write(Scanner s) throws FileNotFoundException, IOException {
System.out.print("작성자 이름? ");
String writer = s.nextLine();
System.out.print("글 내용? ");
String message = s.nextLine();
int seq = 0;
if(list.size() != 0) {
seq = list.get(list.size() – 1).seq + 1;
}
list.add(new Article(seq, writer, message));
System.out.println();
// 직렬화 출력하기: 글이 작성되었으면 메모리의 객체를 직렬화한 뒤
// 물리적인 파일로 하드디스크에 저장한다.
saveToFile();
}
private static void displayBoard() {
System.out.println("순서\t글쓴이\t메시지");
System.out.println("———————–");
if(list.size() == 0) {
System.out.println("[아직 글이 없습니다.]");
}
list.forEach((x) -> {
System.out.println(x);
});
}
private static void saveToFile() throws FileNotFoundException, IOException {
// 파일 출력 스트림 객체를 만든 후, 이름을 "board.ser"라고 지정하고
// fos를 바탕으로 오브젝트 출력 스트림을 생성한 뒤 writeObject 한다.
try(FileOutputStream fos = new FileOutputStream("board.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(list);
}
}
@SuppressWarnings("unchecked")
private static void readFromFile() throws FileNotFoundException, IOException, ClassNotFoundException {
// 파일 입력 스트림 객체를 만든 후, 이름을 "board.ser"라고 지정하면 이 파일로부터 읽겠다는 뜻이며
// fis를 바탕으로 오브젝트 입력 스트림을 생성한 뒤 readObject 한다.
// 오브젝트 형태로 읽으면 안에 있는 내용이 무슨 타입인지 정확히 알기 어려우므로 타입 캐스팅 해준다.
try(FileInputStream fis = new FileInputStream("board.ser");
ObjectInputStream ois = new ObjectInputStream(fis);) {
list = (List<Article>) ois.readObject();
}
}
}

 

껐다 켜도 내용이 그대로 남아있다.

 

문의 | 코멘트 또는 yoonbumtae@gmail.com


카테고리: Java


1개의 댓글

IT 기술면접(일반) 예상문제: CS 일반, 개발 상식, 네트워크 (작성중) - BGSMM · 2020년 6월 12일 12:00 오후

[…] 직렬화란 자바의 객체를 네트워크 상에서 주고받게 하기 위하여 메모리에 저장된 객체를 바이너리 형식으로 변환하는 것을 뜻합니다. 이렇게 변환된 직렬화된 객체는 하드디스크에 저장하거나 네트워크 상으로 전송하여 다른 컴퓨터에서 사용하도록 할 수 있습니다. […]

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다