본문 바로가기
└ JAVA

[Java] 스트림의 개념, 종류/파일 입출력/InputStream/OutputStream/Reader/Writer

by 짜장이누나 2015. 7. 28.


쓸때마다 헷갈리는 파일입출력..

사용할 때 마다 찾아보고 하기도 번거롭고 아직까지도 제대로 모르는 것도 창피하니 이참에 개념부터 확실하게 잡고 가자!!!





★ 자바 스트림

 어떤 목표 지점에서 데이터를 읽어 들이고, 목표 지점에 기록하는 것을 데이터의 Input, Output 작업이라고 합니다. 기본적으로 우리는 모니터로 입출력하는 것을 배웠습니다. 가장 많이 사용하는 System.out.println에서 out은 콘솔 화면에 데이터를 출력하는 것을 담당하고, System.in은 키보드의 입력을 담당하고 있습니다. 여기서 in과 out같이 데이터를 받고 출력하는 작업을 도와주는 중간 역할을 스트림이라고 부릅니다.


자바에서 사용하는 Input과 Output작업의 목표지점은 아래와 같이 아주 다양합니다. 

  • 파일
  • 키보드, 모니터
  • 메모리
  • 네트워트 연결




★ 스트림 (Stream) 이란?

 간단한게 말해서 스트림이란 '자료의 입출력을 도와주는 중간매개체' 입니다. 스트림은 입력과 출력을 도와주는 매개역할을 하는 것이니, 입력과 출력이 관련된 곳이면 어디서든 동작합니다. 스트림을 더 쉽게 설명할 때 아래와 같이 비유하곤 합니다.

  • 스트림은 데이터를 읽고 기록하는 중간역할을 한다.
  • 스트림은 빨대다.
  • 빨대는 음료수를 마시는 중간역할을 한다.
  • 빨대는 입에 있는 음료수를 다시 내뱉는 중간역할을 한다.
  • 스트림은 단 방향 빨대이다. 음료수를 내뱉고 다시 마시려면 빨대가 2개 필요하다.


조금 지저분한 비유이긴 하지만;; 이것을 다시 입력/출력 스트림으로 나누어 비교해보면 아래와 같습니다.

  • 입력 스트림 비교

- 입력 스트림은 데이터를 먼저 스트림으로 읽어 들인다. 그리고 스트림에 존재하는 데이터를 하나씩 일거 들일 수 있다.

- 음료수를 마실 때 빨대를 이용하여 음료수를 빨대에 모으고 빨대에 들어있는 음료수를 흡입한다. 그러면 음료수가 입안으로 들어 올 것이다.


  • 출력 스트림 비교

- 출력 스트림으로 데이터를 보낸다. 출력 스트림에 보낸 데이터를 비워 버린다. 그렇게 되면 출력 스트림에 존재하던 데이터가 모두 목표지점에 저장된다.

- 입 안에 있던 음료수를 빨대로 일단 보낸다. 빨대에 들어있는 음료수를 불어 버린다. 그렇게 되면 음료수는 다시 컵 안으로 들어가게 된다.


이제 쉽죠잉??? 이해가 되죠잉???

이러한 절차를 스트림으로 표현하면 아래와 같습니다.

  • 목표로 하는 제이터를 정한다.
  • 데이터에 맞는 스트림을 생성한다.
  • 스트림 클래스의 멤버 메소드를 이용하여 쉽게 데이터를 핸들한다.
(기록하거나 읽어들이거나, 보내거나 받거나!)


지금까지 스트림에 대해서 정리해보았는데 스트림 개념은 어렵지 않으거 같습니다. 다만 종류가 많다보니... 이걸 다 외울 수도 없고ㅜㅜㅜ 먼저 원리를 이해하기 위해 하나하나 차근차근 설명해보겠습니다. 




★ 스트림의 종류

스트림은 크게 문자 단위로 처리하느냐, 바이트 단위로 처리하느냐에 따라서 나눌 수 있습니다.


◆ 먼저 문자 스트림의 구성도는 아래와 같이 나타납니다. 


 입력 문자 스트림은 Reader라는 단어가 붙어있습니다.


△ 출력 문자 스트림은 Writer라는 단어가 붙어있습니다.



◆ 다음은 바이트 스트림의 구성도를 보겠습니다.


 입력 바이트 스트림은 InputStream라는 단어가 붙어있습니다.


 출력 바이트 스트림은 OutputStream라는 단어가 붙어있습니다. (아닌 것도 있지만 대부분 이 형식에 따름)


InputStream 과 Reader 계열일 경우에는 읽어 들이는 메소드를 포함하고 OutputStream 과 Writer의 경우 문자를 다루는 메소드를 포함합니다.



◆ 입력 스트림 계열의 멤버 메소드

  • 바이트 단위 (InputStream)
- int read()
- int read(byte buf[])
- int read(byte buf[], int offset, int length)


  • 문자 단위 (Reader)
- int read()
- int read(char buf[])
- int read(char buf[], int offset, int length)



 출력 스트림 계열의 멤버 메소드

  • 바이트 단위 (OutputStream)
- int write(int c)
- int write(byte buf[])
- int write(byte buf[], int offset, int length)

  • 문자 단위 (Writer)
- int write(int c)
- int write(char buf[])
- int write(char buf[], int offset, int length)



마지막으로 스트림의 종류와 설명으로 간단하게 정리해 보겠습니다.



◆ 스트림의 종류와 설명

 문자 스트림 클래스

바이트 스트림 클래스 

설명 

 Reader

 InputStream

 문자/바이트 입력 스트림을 위한 추상클래스

 BufferedReader

 BufferedInputStream

 문자/바이트 버퍼 입력, 라인 해석

 LineNumberReader

 LineNumberInputStream

 문자/바이트 입력시, 라인 번호를 유지

 CharArrayReader

 LineNumberInputStream

 문자/바이트 배열에서 읽어들임

 InputStreamReader

 

 바이트 스트림을 문자 스트림으로 변환

 FileReader

 FileInputStream

 파일에서바이트를읽어들여문자/바이트스트림으로 변환

 FilterReader

 FilterInputStream

 필터적용(filtered)문자/바이트입력을위한추상클래스

 PushbackReader

 PushbackInputStream

 읽어들인 문자/바이트를 되돌림(pushback)

 PipedReader

 PipedInputStream

  PipedWriter/PipedOutputStream에서 읽어들임

 StringReader

 StringBufferInputStream

 문자열에서 읽어들임

 Writer

 OutputStream

 문자 출력 스트림을 위한 추상클래스

 BufferedWriter

 BufferedOutputStream

 문자/바이트 스트림에 버퍼 출력, BufferedWriter는 플랫폼에서 사용하는 라인 구분자(line separator) 사용

 CharArrayWriter

 ByteArrayOutputStream

 문자/바이트 스트림에 문자/바이트 배열 출력

 FilterWriter

 FilterOutputStream

 필터적용(filtered)문자/바이트출력을위한추상클래스

 OutputStreamWriter

 

 문자 스트림을 바이트 스트림으로 변환

 FileWriter

 FileOutputStream

 문자/바이트 스트림을 바이트 파일로 변환

 PrintWriter

 PrintStream

 Writer/Streamdp 값과 객체를 프린트

 PipedWriter

 PipedOutputStream

 PipedReader/PipedOutputStream에 출력

 StringWriter

 

 문자열 출력


이것을 다 외울 필요는 없고 하다보면 알게 되겠지...... 익혀지겠지........