Java에서 ObjectOutputStream은 오브젝트를 OutputStream으로 변환하는 데 사용할 수 있습니다. 오브젝트를 스트림으로 변환하는 과정은 Java에서 직렬화(serialization)라고 불립니다. 오브젝트가 Output Stream으로 변환되면 파일이나 데이터베이스에 저장하거나 네트워크를 통해 전송하거나 소켓 연결에 사용할 수 있습니다. 따라서 FileOutputStream을 사용하여 오브젝트를 파일에 쓸 수 있습니다.
ObjectOutputStream
ObjectOutputStream은 Java IO 클래스의 일부이며, 그 목적은 Java 오브젝트를 스트림으로 변환하는 방법을 제공하는 것입니다. ObjectOutputStream의 인스턴스를 생성할 때 사용할 OutputStream을 제공해야 합니다. 이 OutputStream은 ObjectOutputStream에 의해 하위 출력 스트림(예: FileOutputStream)에 대한 오브젝트 스트림을 전달하는 데 사용됩니다.
ObjectOutputStream 요구사항
우리가 직렬화하려는 객체는 java.io.Serializable
인터페이스를 구현해야합니다. Serializable은 단순히 마커 인터페이스이며 구현해야 할 추상 메서드가 없습니다. 클래스가 Serializable 인터페이스를 구현하지 않은 경우 java.io.NotSerializableException
을 얻게됩니다. 아래와 같은 예외 스택 트레이스와 같은 것입니다.
java.io.NotSerializableException: com.journaldev.files.EmployeeObject
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at com.journaldev.files.ObjectOutputStreamExample.main(ObjectOutputStreamExample.java:21)
파일에 객체를 쓰는 Java ObjectOutputStream 예제
파일에 객체를 쓰기 위한 Java ObjectOutputStream 예제를 살펴보겠습니다. 우선, 몇 가지 속성이있는 클래스가 있어야합니다. 파일에 저장할 객체를 만들어 보겠습니다.
package com.journaldev.files;
import java.io.Serializable;
public class Employee implements Serializable {
private static final long serialVersionUID = -299482035708790407L;
private String name;
private String gender;
private int age;
private String role;
// private transient String role;
public Employee(String n) {
this.name = n;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String toString() {
return "Employee:: Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender + " Role=" + this.role;
}
}
모든 속성에 대해 getter/setter를 가져야하는 요구 사항이 아닌 것에 유의하십시오. 또는 무인자 생성자를 가져야합니다. 위의 Employee 객체에는 “name” 속성에 대한 getter/setter 메서드가 없습니다. 그리고 무인자 생성자도 없습니다. 다음은 ObjectOutputStream을 사용하여 Java에서 파일로 객체를 쓰는 방법을 보여주는 프로그램입니다.
package com.journaldev.files;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamExample {
public static void main(String[] args) {
Employee emp = new Employee("Pankaj");
emp.setAge(35);
emp.setGender("Male");
emp.setRole("CEO");
System.out.println(emp);
try {
FileOutputStream fos = new FileOutputStream("EmployeeObject.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 객체를 파일에 쓰기
oos.writeObject(emp);
System.out.println("Done");
// 리소스 닫기
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
다음 이미지는 위 프로그램의 출력을 보여줍니다. 만약
EmployeeObject.ser
파일의 내용이 궁금하다면, 약간 난해하고 아래와 같을 것입니다.
��srcom.journaldev.files.Employee�����yyIageLgendertLjava/lang/String;Lnameq~Lroleq~xp#tMaletPankajtCEO
transient를 사용한 ObjectOutputStream
스트림으로 변환되기를 원치 않는 객체 속성이 있다면 해당 속성에 대해 transient 키워드를 사용해야 합니다. 예를 들어 역할 속성을 아래처럼 변경하면 저장되지 않습니다.
private transient String role;
ObjectOutputStream와 serialVersionUID
Employee 객체에 정의된 serialVersionUID
를 주목했나요? 이는 ObjectOutputStream
및 ObjectInputStream
클래스에서 객체 작성 및 읽기 작업에 사용됩니다. 이 필드가 필수는 아니지만 유지하는 것이 좋습니다. 그렇지 않으면 클래스를 변경해도 이전에 직렬화된 객체에 영향을 미치지 않으므로 실패할 수 있습니다. 자세한 분석은 Java에서 직렬화로 이동하세요. 프로그램이 제대로 작동했는지 궁금하다면 저장된 파일에서 객체를 읽기 위해 아래 코드를 사용하세요.
FileInputStream is = new FileInputStream("EmployeeObject.ser");
ObjectInputStream ois = new ObjectInputStream(is);
Employee emp = (Employee) ois.readObject();
ois.close();
is.close();
System.out.println(emp.toString());
//Output will be "직원:: 이름=Pankaj 나이=35 성별=남성 역할=CEO"
이것이 자바 ObjectOutputStream 및 파일에 객체를 쓰는 방법에 대한 모든 것입니다.
더 많은 자바 IO 예제는 우리의 GitHub 저장소에서 확인할 수 있습니다.
참고: API 문서
Source:
https://www.digitalocean.com/community/tutorials/objectoutputstream-java-write-object-file