본문 바로가기

프로그래밍 언어/JAVA

JAVA 입문 - 자바 입출력과 스트림

지난 글: [프로그래밍 언어/JAVA] - JAVA 입문 - 사용자 정의 예외

 

입출력은 프로그램의 가장 기본 기능이지만, 외부 저장 장치나 네트워크와 연동해야 하기에 장치에 따라 다르게 구현한다. 자바는 장치에 따라 독립적이고 효율적인 입출력 기능을 제공한다.

 

스트림이란?

자바에서 모든 입출력은 스트림(stream)을 통해 이루어진다. 스트림이란 네트워크에서 유래된 용어이며 자료 흐름이 물의 흐름과 같다는 의미에서 사용됐다. 입출력 장치는 매우 다양하기에 장치에 따라 입출력 부분을 일일이 다르게 구현하면 프로그램의 호환성이 떨어진다. 이런 문제를 해결하기 위해 자바는 입출력 장치와 무관하고 일관성 있게 프로그램을 구현할 수 있도록 일종의 가상 통로인 스트림을 제공하는 것이다. 자료를 읽어 들이려는 소스(source)와 자료를 쓰려는 대상(target)에 따라 각각 다른 스트림 클래스를 제공한다. 

 

자바에서 입출력 기능을 사용하는 곳은 파일 디스크, 키보드, 모니터, 메모리 입출력, 네트워크 등이 있다. 이런 곳에서 일어나는 모든 입출력 기능을 스트림 클래스로 제공한다. 따라서 자바에서 자료를 입출력하려면 여러 스트림 클래스에 대해 알아야 한다. 다행히도 스트림 클래스의 구현 방식은 서로 비슷하다고 한다. 우선 스트림을 세 가지 기준에 따라 분류한다.

 

입력 스트림과 출력 스트림

입력 스트림은 어떤 대상으로부터 자료를 읽어 들일 때 사용하는 스트림이다. 예로 어떤 동영상을 재생하기 위해 동영상 파일에서 자료를 읽을 때 사용한다. 편집 화면에 사용자가 쓴 글을 파일에 저장할 때는 출력 스트림을 사용한다. 스트림은 단방향으로 자료가 이동하기에 입력과 출력을 동시에 할 수 없다. 입력 자료의 이동이 출력 자료의 이동과 한 스트림에서 동시에 일어날 수 없기 때문이다.

 

스트림의 이름을 보면 입력용인지 출력용인지 알 수 있다. InputStream이나 Reader로 끝나는 이름의 클래스는 입력 스트림, OutputStream이나 Writer로 끝나는 이름의 클래스는 출력 스트림이다.

 

바이트 단위 스트림과 문자 단위 스트림

원래 자바의 스트림은 바이트(byte) 단위로 자료의 입출력이 이루어진다. 그러므로 그림, 동영상, 음악 파일 등 대부분 파일은 바이트 단위로 읽거나 쓰면 된다. 그런데 자바에서 하나의 문자를 나타내는 char형은 2바이트이기에 1바이트만 읽으면 한글 같은 문자는 깨진다. 따라서 입출력 중 가장 많이 사용하는 자료인 문자를 위해 문자 스트림을 별도 제공한다. 즉 읽어 들이는 자료형에 따라 바이트용과 문자용 스트림이 있다.

 

스트림 클래스의 이름이 Stream으로 끝나는 경우는 바이트 단위를 처리하는 스트림, Reader나 Writer로 끝나는 이름은 문자를 위한 스트림이다.

 

기반 스트림과 보조 스트림

스트림이 자료를 직접 읽거나 쓰는 기능을 제공하는지, 아니면 자료를 직접 읽거나 쓰는 기능은 없이 다른 스트림에 부가 기능을 제공하는지에 따라 기반 스트림과 보조 스트림으로 구분할 수 있다. 기반 스트림은 읽어 들일 곳(소스)이나 써야 할 곳(대상)에서 직접 읽고 쓸 수 있으며 입출력 대상에 직접 연결되어 생성되는 스트림이다. 반면 보조 스트림은 직접 읽고 쓰는 기능이 없다. 따라서 항상 다른 스트림을 포함하여 생성된다. 아래 그림처럼 기반 스트림에 보조 스트림을 더해 기능을 추가한다.

기반 스트림인가 보조 스트림인가 여부는 이름으로 판단하기 어려울 수 있다. 그러므로 실무에서 많이 사용된다는 클래스 위주로 기억하자.

 

하나의 스트림 클래스는 세 가지 분류로 나눌 수 있다. 예로 FileInputStream을 보면 InputStream이니 입력 스트림이고, Stream이니 바이트 단위로 처리하며, File에 직접 읽고 쓰는 기반 스트림이다. 즉 자바 스트림 클래스 이름에서 스트림 특성을 유추할 수 있다. 각 스트림을 사용하는 메서드도 거의 같다고 한다.

 

참고 서적 : 자바 프로그래밍 입문 - 박은종