Java ObjectOutputStream 마스터하기: 직렬화, 메서드, 실전 예제
Java ObjectOutputStream 클래스
Java ObjectOutputStream API, 핵심 메서드, 객체를 파일에 직렬화하고 다시 읽는 과정을 보여주는 단계별 예제를 탐구합니다.
java.io 패키지의 ObjectOutputStream 클래스는 나중에 ObjectInputStream으로 읽을 수 있도록 Java 객체를 쓸 수 있게 합니다. OutputStream을 확장하며 Java 내장 직렬화 메커니즘의 중추입니다.
ObjectOutputStream 작동 원리
ObjectOutputStream에 객체를 쓰면 프레임워크는 객체의 클래스 이름, 필드 값, 타입 정보를 이진 형식으로 인코딩합니다. 이 과정을 직렬화라고 합니다. 결과 바이트 스트림은 파일에 저장하거나 네트워크를 통해 전송하거나 메모리에 임베드할 수 있습니다.
중요: java.io.Serializable을 구현한 객체만 직렬화할 수 있습니다. 이 인터페이스는 객체가 지속되거나 전송하기에 안전함을 런타임에 알리는 마커 역할을 합니다.
ObjectOutputStream 생성하기
클래스를 임포트하는 것으로 시작합니다:
import java.io.ObjectOutputStream;
그런 다음 FileOutputStream이나 다른 OutputStream에 연결합니다:
// "data.bin"이라는 파일에 쓰기
FileOutputStream fileStream = new FileOutputStream("data.bin");
ObjectOutputStream objStream = new ObjectOutputStream(fileStream);
이제 objStream은 객체를 fileStream으로 직렬화할 준비가 되었습니다.
ObjectOutputStream의 핵심 메서드
이 클래스는 OutputStream에서 메서드 세트를 상속하고 객체 처리를 위한 특화된 메서드들을 추가합니다:
write(int b) - 단일 바이트를 씁니다.
writeBoolean(boolean v) - 불리언 값을 씁니다.
writeChar(int v) - 문자를 씁니다.
writeInt(int v) - 정수를 씁니다.
writeObject(Object obj) - 주어진 객체를 직렬화합니다.
예제 1: 기본 타입과 문자열 직렬화
아래는 int와 String을 파일에 쓴 다음 ObjectInputStream으로 다시 읽는 완전한 스니펫입니다:
import java.io.*;
public class Main {
public static void main(String[] args) {
int data1 = 5;
String data2 = "This is programiz";
try {
// 객체 쓰기
FileOutputStream fos = new FileOutputStream("file.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(data1);
oos.writeObject(data2);
oos.close();
// 객체 읽기
FileInputStream fis = new FileInputStream("file.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.println("Integer data :" + ois.readInt());
System.out.println("String data :" + ois.readObject());
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
실행 결과
Integer data :5
String data :This is programiz
예제 2: 커스텀 객체 직렬화
사용자 정의 클래스를 직렬화하려면 단순히 Serializable을 구현하면 됩니다:
import java.io.*;
class Dog implements Serializable {
String name;
String breed;
Dog(String name, String breed) {
this.name = name;
this.breed = breed;
}
}
public class Main {
public static void main(String[] args) {
Dog dog1 = new Dog("Tyson", "Labrador");
try {
// 객체 쓰기
FileOutputStream fos = new FileOutputStream("dog.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(dog1);
oos.close();
// 객체 읽기
FileInputStream fis = new FileInputStream("dog.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
Dog newDog = (Dog) ois.readObject();
System.out.println("Dog Name: " + newDog.name);
System.out.println("Dog Breed: " + newDog.breed);
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
실행 결과
Dog Name: Tyson
Dog Breed: Labrador
Dog 클래스는 ObjectOutputStream이 직렬화 가능한 객체만 쓸 수 있으므로 Serializable을 구현해야 합니다.
추가 ObjectOutputStream 연산
| 메서드 | 설명 |
flush() | 버퍼링된 출력 바이트를 기본 스트림으로 플러시합니다. |
drain() | 버퍼링된 데이터를 플러시합니다(Java 9+에서 사용 가능). |
close() | 스트림을 닫고 시스템 리소스를 해제합니다. |
더 깊은 이해를 위해 공식 Java 문서를 참조하세요.