1) 문자 인코딩
문자 인코딩: 문자 집합을 통해 문자->숫자로 변환하는 것
문자 디코딩: 문자 집합을 통해 숫자 -> 문자로 변환하는 것
UTF-8이 현대의 표준 인코딩 기술이다 - 저장 공간 절약 & 네트워크 효율성
2) 스트림
public class FileMemberRepository implements MemberRepository {
private static final String FILE_PATH = "temp/members-txt.dat";
private static final String DELIMITER = ",";
@Override
public void add(Member member) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_PATH, UTF_8, true))){
bw.write(member.getId() + DELIMITER + member.getName() + DELIMITER + member.getAge());
bw.newLine(); // 다음 줄로 이동함
}catch (IOException e){
throw new RuntimeException(e);
}
}
@Override
public List<Member> findAll() {
List<Member> members = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader(FILE_PATH, UTF_8))){
String line;
while((line = br.readLine()) != null){
String [] memberData = line.split(DELIMITER);
//파일에 읽은 데이터를 기반으로 회원 객체 생성
members.add(new Member(memberData[0], memberData[1], Integer.valueOf(memberData[2])));
}
return members;
}catch (FileNotFoundException e){
return new ArrayList<>();
}catch (IOException e){
throw new RuntimeException(e);
}
}
}
line=br.readLine()을 통해 각 회원 하나하나를 불러온다.
회원 데이터를 DELIMETER 구분자로 구분해서 배열에 담는다.
members.add()함수로 파일에 읽은 데이터를 기반으로 회원 객체를 생성한다.
id,name은 String이지만 age는 문자로 조회했기 때문에 Integer로 변경해야 한다.
3) ObjectStream
: 회원 인스턴스는 메모리 어딘가에 보관돼있는데 이 객체를 읽어서 파일에 저장할 때 ObjectStream을 사용한다.
> 객체 직렬화
: 메모리에 있는 객체 인스턴스를 바이트 스트림으로 변환해 파일에 저장하거나 네트워크로 전송한다.
이 과정에서 객체의 상태를 유지하여 나중에 역직렬화로 원래의 객체로 복원할 수 있다.
public class ObjectMemberRepository implements MemberRepository{
private static final String FILE_PATH = "temp/members-txt.dat";
@Override
public void add(Member member) {
List<Member> members = findAll();
members.add(member);
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_PATH))){
oos.writeObject(members);
}catch (IOException e){
throw new RuntimeException(e);
}
}
@Override
public List<Member> findAll() {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_PATH))){
Object findObject = ois.readObject();
return (List<Member>) findObject;
}catch (FileNotFoundException e){
return new ArrayList<>();
}catch (IOException | ClassNotFoundException e){
throw new RuntimeException(e);
}
}
}
ObjectOutputStream로 객체 인스턴스를 직렬화해서 byte로 변경할 수 있다.
우리는 회원 객체 하나가 아니라 회원 목록 전체를 파일에 저장해야 하므로 members 컬렉션을 직렬화 해야한 다.
oos.writeObject(members)를 호출하면 members 컬렉션과 그 안에 포함된 Member를 모두 직렬화해 서 byte로 변경한다.
그리고 oos와 연결되어 있는 FileOutputStream에 결과를 출력한다.
4) 정리
회원 정보를 계속 유지하려면 파일에 저장해야 한다.
그런데 Member 객체는 자바 메모리에만 있는 "객체"라서, 파일에 저장하려면 byte로 변환(=직렬화) 해야 함
자바에서는 ObjectOutputStream을 이용해 객체를 직렬화할 수 있고 반대로 byte → 객체로 복원하는 건 역직렬화(ObjectInputStream)로 가능하다.
직렬화 대상 클래스인 Member에는 public class Member implements Serializable로 구현해야 함!!
- add 함수
: oos.writeObject(members)는 List<Member> 전체를 한꺼번에 byte로 변환해서 파일에 씀
그 안에 들어있는 Member 객체들도 자동으로 함께 직렬화됨
- findAll 함수
: 파일에서 읽어올 땐 readObject() 사용해서 byte를 객체로 역직렬화
저장된 전체 회원 목록을 다시 List<Member>로 되살림
'Spring' 카테고리의 다른 글
[8] 자바 고급 문법 - 람다 & 스트림 (0) | 2025.03.31 |
---|---|
[6] 자바 중급 문법 - List (0) | 2025.03.28 |
[5] 자바 중급 문법 - ArrayList (0) | 2025.03.28 |
[4] 자바 중급 문법 - Generic (0) | 2025.03.26 |
[3] 자바 중급 문법 3 -- 날짜와 시간 (0) | 2025.03.21 |