I/O-Stream

logY·2023년 1월 27일
0

Java

목록 보기
4/4

I/O와 Stream

  • I/O? 데이터의 입력(input)과 출력(output)
  • 데이터는 한쪽에서 주고 한쪽에서 받는 구조로 되어있다.
  • 이때 입력과 출력의 끝단을 노드(Node)라고 한다!

노드 스트림

Node Stream의 종류와 naming

  • 데이터의 타입에 따라 → byte? char?
  • 방향에 따라 → 입력? 출력?
  • 노드 타입에 따라 → 키보드, 모니터, File, ByteArray, Pipe…..(자세한 내용은 아래 그림을 참고)

❗ 너무 많아도 너무 많은데… 하지만 우리에게는 `인터페이스`가 있다!!!

InputStream의 주요 메서드

read()

  • public abstract int read() throws IOException → byte 하나를 읽어서 int로 반환한다. 더 이상 읽을 값이 없으면 -1을 리턴한다…. (자세한 내용은 그림을 참고…) 👍


)

close()

  • public void close() throws IOException → 스트림을 종료해서 자원을 반납한다.
private String data1 = "hi java world";

    private void read1() {
        // TODO: data1를 읽어보자.
        try (InputStream input = new ByteArrayInputStream(data1.getBytes())) {
            int read = -1;
            while ((read = input.read()) != 1) {
                System.out.printf("읽은 값: %d, %c\n", read, read);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // END:
    }
private String data2 = "자바는 객체지향 언어입니다.";

    private void read2() {
        // TODO: data2를 읽어보자.
        byte[] buffer = new byte[10];
        try (InputStream input = new ByteArrayInputStream(data2.getBytes())) {
            int read = -1;
            while ((read = input.read()) > 0) {
                System.out.printf("읽은 개수: %d, %s\n", read, new String(buffer, 0, read));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // END:
    }
private String data2 = "자바는 객체지향 언어입니다.";

private void read3() {
        // TODO: data2를 읽어보자.
        byte[] buffer = new byte[10];
        try (Reader input = new CharArrayReader(data2.toCharArray())) {
            int read = -1;
            while ((read = input.read()) > 0) {
                System.out.printf("읽은 개수: %d, %s\n", read, new String(buffer, 0, read));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // END:
    }

OutputStream

❗ 굳이 문자열을 byte와 buffer로 나눠서 입력하고 출력해야하는 거야…? `System.out.print`쓰면 되는 거 아님?? 쓸모 없는데 만들지 않았겠지~~ 파일을 읽고 쓰는데 사용한다구~~ 📁

File

가장 기본적인 입출력 장치 중 하나로 파일과 디렉터리를 다루는 클래스

❓ 파일을 읽어들일 때 어떤 기준으로 파일을 지정해주지? 여기에는 두가지 방법이 있어 상대경로 → 나(현재 파일)를 기준으로 파일의 경로를 지정 절대경로 → 컴퓨터의 root를 기준으로 파일의 경로를 지정

상대경로

  • 현재 파일을 기준으로 파일의 경로를 지정
  • 집중집중 💥 → 여기서 현재 파일의 위치가 아니라 프로그램을 실행하는 위치!!!! (무슨 소리야…ㅠㅠ) → 그냥 절대 경로 쓰면 되는 거 아냐??? 💢

너무 어려운뎅….ㅠㅠㅠㅠㅠ → 자율학습시간에 다시 정리해보자…

❓ char와 byte 둘중 어떤 것을 쓸지 어떻게 결정하지? char는 메모장이 인코딩할 수 있는 것!!! byte는 플러그인이 필요한 파일!!! 잠깐!! 여기서 byte는 한글이 깨지니까 주의해주세요! byte는 1byte를 기준으로 처리하기 때문!!! 파일을 복사할 때는 byte단위로 파일을 저장하니까 한글 처리를 안해줘도 되지!

보조 스트림

다른 스트림의 부가적인 기능을 제공하는 스트림

  • 문자 set 변환
  • Buffering
  • 기본 데이터 형의 전송
  • 객체 입출력

스트림 체이닝(Stream Chaining)

  • 필요에 따라 여러 보조 스트림을 연결해서 사용 가능
  • 보조 스트림을 사용하기 위해서는 node스트림이 반드시 필요하다!!!!
  • 보조 스트림은 노드 스트림에 파츠처럼 붙여서 사용!!!

보조 스트림의 종류

❓ 이 친구들 백준 문제 풀때 사용한 거 같은데… [이 문제(클릭!)](https://www.acmicpc.net/problem/15552)
  • byte 스트림을 char 스트림으로 변환
    • InputStreamReader
    • OutputStreamWriter
  • 버퍼링을 통한 속도 향상
    • BufferedInputStream
    • BufferedOutputStream
  • 객체 전송
    • ObjectInputStream
    • ObjectOutputStream

ㅇㅎ 보조 스트림의 인자로는 노드 스트림이 오는구나!!!!!

사용할 스트림의 결정 과정

  • 노드가 무엇인가 → 타입은 문자열인가? 바이트인가? → 방향이 무엇인가? → 추가 기능이 필요한가?

그림으로 예시를 알아보자~~

BufferedReader는 속도를 향상시켜주는구나!!! → 알고리즘 원툴인줄… 🥲

보조스트림 활용

Buffered 계열

객체 직렬화(serialization)

  • 객체를 파일등에 저장하거나 네트워크로 전송하기 위해 연속적인 데이터로 변환하는 것
  • 반대의 경우는 역 직렬화(deserialization)

직렬화 되기 위한 조건!

  • Serializable인터페이스를 구현해야 돼!
  • 데이터를 전송하려면 중요한 데이터를 빼야하는데? → transient를 선언해서 해결할 수 있지~
  • serialVersionUID
    • 움.. 만약에 클래스가 변경되었다면 그걸 어떻게 구별하지…?

    • 그래서 필요한 것이 serialVersionUID!!!

    • 클래스를 버전으로 구별한다고 생각하면 돼! (최종, 찐최종, 찐찐최종…..)

    • 버전이 다르면? 역직렬화를 할 수 없다구~

      ❓ `serailVersionUID`를 설정 안해주면 어떻게 되지? 컴파일러가 자동으로 생성해줘! 하지만!!! 버전을 직접 명시해줌으로서 변경된 클래스도 역직렬화 가능하도록 할 수도 있다구~ → 근데… 변경된 내용은 적용되지 않아!
profile
백엔드 개발자

0개의 댓글