1. ObjectInputSteam, ObjectOutputStream
- 직렬화 가능한 대상을 읽고, 쓸 수 있다.
- 직렬화 가능한 대상은 기본형 타입 또는 java.io.Serializable 인터페이스를 구현하고 있는 객체이다.
- Serializable - 메소드가 없는 인터페이스로 마크 인터페이스라고 부른다
- 객체 직렬화란? 데이터 구조를 다른 환경에 전송/저장하기 위하여 바이트(Byte) 포맷으로 변환하는 과정을 말한다.
- write object -> byte흐름으로 변경되어 전송 -> file, memory에 저장 --역직렬화--> Object(객체)
2. 코드로 작성하기
2-1. Serializable 인터페이스를 구현한 User class 작성
package io;
import java.io.Serializable;
public class User implements Serializable {
private String name; //String은 Serializable을 구현하고있다
private String email;
private int birthYear; //기본형 타입이므로 Serializable을 구현하고있다.
//Serializable을 구현하고 있지 않은 타입을 가진 필드는 직렬화할 수 없다..
public User(String name, String email, int birthYear) {
this.name = name;
this.email = email;
this.birthYear = birthYear;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public int getBirthYear() {
return birthYear;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", email='" + email + '\'' +
", birthYear=" + birthYear +
'}';
}
}
2-2. File에 Object를 타입으로 갖는 ArrayList 쓰기
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
public class ObjectOutputExam {
public static void main(String[] args) throws Exception {
User user1 = new User("홍길동", "hong@example.com", 1992);
User user2 = new User("고길동", "go@example.com", 1970);
User user3 = new User("둘리", "dool@example.com", 100);
ArrayList<User> arrayList = new ArrayList<>(); //Serializable을 구현하고있다.
arrayList.add(user1);
arrayList.add(user2);
arrayList.add(user3);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/tmp/userList.dat"));
out.writeObject(arrayList);
out.close();
}
}
2-3. File에 Object를 타입으로 갖는 ArrayList 읽어오기
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class ObjectInputExam02 {
public static void main(String[] args) throws Exception{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("/tmp/userList.dat"));
ArrayList<User> array = (ArrayList)in.readObject();
in.close();
for (User user: array) {
System.out.println(user);
}
}
}
2-4. Object IO Stream과 Byte Array IO Stream을 이용한 얕은복사, 깊은 복사
import java.io.*;
import java.util.ArrayList;
public class ObjectInputOutputExam {
public static void main(String[] args) throws Exception {
User user1 = new User("홍길동", "hong@example.com", 1992);
User user2 = new User("고길동", "go@example.com", 1970);
User user3 = new User("둘리", "dool@example.com", 100);
ArrayList<User> originalList = new ArrayList<>(); //Serializable을 구현하고있다.
originalList.add(user1);
originalList.add(user2);
originalList.add(user3);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/tmp/userList.dat"));
out.writeObject(originalList);
out.close();
System.out.println();
System.out.println("----------얕은 복사 확인하기----------");
System.out.println();
//얕은 복사 확인하기
// ArrayList<User> shallowCopiedList = new ArrayList<>();
//
// for (User user: originalList) {
// shallowCopiedList.add(user); //얕은 복사(두 ArrayList가 같은객체를 바라봄)
// }
//originalList.remove(0);를 통해 originalList에서 원소를 삭제하더라도,
// shallowCopiedList의 크기에는 영향을 주지 않습니다. 여기서 중요한 점은, 실제 객체에 대한 참조는 공유되지만,
// 리스트의 크기나 구조에 대한 정보는 각 리스트가 독립적으로 가지고 있기 때문입니다.
ArrayList<User> shallowCopiedList = originalList;
System.out.println( "originalList "+ originalList.size());
System.out.println("shallowCopiedList " + shallowCopiedList.size());
originalList.remove(0);
System.out.println("originalList index0번 삭제");
System.out.println( "originalList "+ originalList.size());
System.out.println("shallowCopiedList " + shallowCopiedList.size());
System.out.println();
System.out.println("----------깊은 복사하기----------");
System.out.println();
//객체 직렬화가 필요
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ObjectOutputStream oOut = new ObjectOutputStream(bOut);
oOut.writeObject(originalList);
oOut.close();
oOut.close();
// byte[] byteArrayList = bout.toByteArray();
ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
ObjectInputStream oIn = new ObjectInputStream(bIn);
ArrayList<User> deepCopiedList = (ArrayList<User>)oIn.readObject(); //arrayList3의 원소를 arrayList4에 깊은 복사
oIn.close();
bIn.close();
System.out.println("deepCopiedList");
originalList.remove(0);
for(User otherUser : deepCopiedList) {
System.out.println(otherUser);
}
System.out.println();
System.out.println("shallowCopiedList");
for(User anotherUser : shallowCopiedList) {
System.out.println(anotherUser);
}
System.out.println();
System.out.println("originalList");
for(User theOtherUser : originalList) {
System.out.println(theOtherUser);
}
}
}
'Java > 기초' 카테고리의 다른 글
[Java] Iterable 인터페이스와 Iterator (0) | 2023.11.01 |
---|---|
[Java] Network Programming(네트워크 프로그래밍) (0) | 2023.11.01 |
[Java] JavaIO - (3)Data, ByteArray, StringReaderWriter (0) | 2023.10.27 |
[Java]JavaIO - (2)FileIOStream (0) | 2023.10.25 |
[Java] JavaIO - (1) (0) | 2023.10.25 |