김영한의 실전 자바 - 고급 2편(스트림 활용)

2025. 1. 25. 00:27·김영한의 실전 자바 - 고급 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);
        }
    }
}
  • BufferedWriter, FileWriter, BufferedReader, FileReader를 사용해 객체를 파일에 저장
  • 객체의 내부 변수를 구분짓기 위해 delimiter를 사용함
  • Integer는 Integer.valueOf와 같은 함수 사용

 

파일에 DataStream을 활용해 회원 정보를 저장/읽는 아래 코드를 설명하시오

public class DataMemberRepository implements MemberRepository {
    private static final String FILE_PATH = "temp/members-data.dat";

    @Override
    public void add(Member member) {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(FILE_PATH, true))) {
            dos.writeUTF(member.getId());
            dos.writeUTF(member.getName());
            dos.writeInt(member.getAge());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<Member> findAll() {
        List<Member> members = new ArrayList<>();
        try (DataInputStream dis = new DataInputStream(new FileInputStream(FILE_PATH))) {
            while (dis.available() > 0) {
                members.add(new Member(dis.readUTF(), dis.readUTF(), dis.readInt()));
            }
            return members;
        } catch (FileNotFoundException e) {
            return new ArrayList<>();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
  • DataStream을 사용하면 UTF로 저장할지, Int로 저장할지 등을 지정할 수 있음.
  • 구분자를 사용할 필요도 없고 자바 타입을 그대로 사용할 수 있음.
  • 데이터를 바이트 효율적으로 저장할 수 있음.
  • 구분자 없이 저장할 수 있는 이유는 몇바이트가 사용될지를 명시하기 때문
  • 예를 들어서, 데이터 스트림은 예를 들어 id1을 저장한다면 3id1 이런식으로 3(뒤에 3바이트가 사용된다) + id1(3바이트) 이런식으로 저장을 하기 때문.
  • 앞에 숫자 3은 2바이트를 사용한 숫자임.

 

파일에 ObjectStream을 활용해 회원 정보를 저장/읽는 아래 코드를 설명하시오

public class ObjectMemberRepository implements MemberRepository {
    private static final String FILE_PATH = "temp/members-obj.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);
        }
    }
}
  • public class Member implements Serializable 이런식으로 Member를 Serializable을 implements 하게 하면 Object를 Serialize 가능함
  • Object의 변수단위로 저장할 필요 없이 Object를 통체로 바로 시리얼라이즈 해서 저장 가능.
  • 객체 직렬화는 여러 문제들이 발생하여 현재는 전혀 사용하지 않음.
  • 사이즈 문제, 성능 문제, 플랫폼 종속성, 버전 관리 어려움 등

 

XML에 대해 설명하시오

<member>
  <id>id1</id>
  <name>name1</name>
  <age>20</age>
</member>
  • 플랫폼 종속성 문제를 해결하기 위해 2000년대 초반에 XML이라는 기술이 인기를 끌었다.
  • 하지만 XML은 매우 유연하고 강력했지만, 복잡성과 무거움이라는 문제가 있었다.
  • 태그를 포함한 XML 문서의 크기가 커서 네트워크 전송 비용도 증가했다.

 

JSON에 대해 설명하시오

{ "member": { "id": "id1", "name": "name1", "age": 20 } }
  • JSON은 가볍고 간결하며, 자바스크립트와의 자연스러운 호환성 덕분에 웹 개발자들 사이에서 빠르게 확산되었다.
  • 2000년대 후반, 웹 API와 RESTful 서비스가 대중화되면서 JSON은 표준 데이터 교환 포맷으로 자리 잡았다.
  • XML은 데이터 구조의 복잡성과 엄격한 스키마 정의가 필요한 초기 웹 서비스와 엔터프라이즈 환경에서 중요한 역할을 했지만, 시간이 지나면서 JSON과 같은 가볍고 효율적인 데이터 형식이 더 많이 채택되었다.
  • JSON은 웹과 모바일 애 플리케이션의 발전과 함께 급속히 인기를 얻었으며, 현재는 대부분의 데이터 교환에서 기본적인 포맷으로 사용되고 있다.
  • XML은 특정 영역에서 여전히 사용되지만, JSON이 현대 소프트웨어 개발의 주류로 자리 잡았다. 지금은 웹 환경에서 데이터를 교환할 때 JSON이 사실상 표준 기술이다.

 

Protobuf, Avro에 대해 설명하시오

  • JSON은 거의 모든 곳에서 호환이 가능하고, 사람이 읽고 쓰기 쉬운 텍스트 기반 포맷이어서 디버깅과 개발이 쉽다.
  • 만약 매우 작은 용량으로 더 빠른 속도가 필요하다면 Protobuf, Avro 같은 대안 기술이 있다.
  • 이런 기술은 호환성은 떨어지지만 byte 기반에, 용량과 성능 최적화가 되어 있으므로 매우 빠르다.
  • 다만 byte 기반이므로 JSON처럼 사람이 직접 읽기는 어렵다

'김영한의 실전 자바 - 고급 2편' 카테고리의 다른 글

김영한의 실전 자바 - 고급 2편(네트워크 예외)  (2) 2025.01.28
김영한의 실전 자바 - 고급 2편(네트워크 자원정리)  (1) 2025.01.28
김영한의 실전 자바 - 고급 2편(네트워크, TCP, IP, UDP, DNS)  (1) 2025.01.28
김영한의 실전 자바 - 고급 2편(스트림)  (2) 2025.01.23
김영한의 실전 자바 - 고급 2편(ASCII, UTF)  (0) 2025.01.23
'김영한의 실전 자바 - 고급 2편' 카테고리의 다른 글
  • 김영한의 실전 자바 - 고급 2편(네트워크 자원정리)
  • 김영한의 실전 자바 - 고급 2편(네트워크, TCP, IP, UDP, DNS)
  • 김영한의 실전 자바 - 고급 2편(스트림)
  • 김영한의 실전 자바 - 고급 2편(ASCII, UTF)
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      @discriminatorcolumn
      프록시
      프록시 팩토리
      requset scope
      jdk 동적 프록시
      고급
      gesingleresult
      페치 조인
      reentarantlock
      빈 후처리기
      조회 성능 최적화
      버퍼
      양방향 맵핑
      김영한
      Thread
      typequery
      @within
      log trace
      JPQL
      cglib
      @discriminatorvalue
      hibernate5module
      자바
      스레드
      단방향 맵핑
      @args
      락
      WAS
      Target
      jpq
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    김영한의 실전 자바 - 고급 2편(스트림 활용)
    상단으로

    티스토리툴바